home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / misc / emu / amiSPIMsrc.lha / cl-cycle.c < prev    next >
C/C++ Source or Header  |  1994-01-17  |  71KB  |  3,222 lines

  1. /* SPIM S20 MIPS Cycle Level simulator.
  2.    Definitions for the SPIM S20 Cycle Level Simulator (SPIM-CL).
  3.    Copyright (C) 1991-1992 by Anne Rogers (amr@cs.princeton.edu) and
  4.    Scott Rosenberg (scottr@cs.princeton.edu)
  5.    ALL RIGHTS RESERVED.
  6.  
  7.    SPIM-CL is distributed under the following conditions:
  8.  
  9.      You may make copies of SPIM-CL for your own use and modify those copies.
  10.  
  11.      All copies of SPIM-CL must retain our names and copyright notice.
  12.  
  13.      You may not sell SPIM-CL or distributed SPIM-CL in conjunction with a
  14.      commerical product or service without the expressed written consent of
  15.      Anne Rogers.
  16.  
  17.    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  18.    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  19.    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20.    PURPOSE.
  21. */
  22.  
  23. /* $Header: /home/primost/larus/Software/SPIM/RCS/cl-cycle.c,v 1.6 1993/05/17 20:46:00 larus Exp $
  24. */
  25.  
  26. /* Cycle Level Simulator -- Anne Rogers, 4 July 91 */
  27.  
  28.  
  29. #ifdef mips
  30. #define _IEEE 1
  31. #include <nan.h>
  32. #else
  33. #define NaN(X) 0
  34. #endif
  35.  
  36. #include <math.h>
  37. #include <stdio.h>
  38. #include <X11/Intrinsic.h>
  39. #include <X11/StringDefs.h>
  40.  
  41. #include "spim.h"
  42. #include "inst.h"
  43. #include "reg.h"
  44. #include "mem.h"
  45. #include "read-aout.h"
  46. #include "spim-utils.h"
  47. #include "sym-tbl.h"
  48. #include "y.tab.h"
  49. #include "mips-syscall.h"
  50.  
  51. #include "cl-mem.h"
  52. #include "cl-cache.h"
  53. #include "cl-cycle.h"
  54. #include "cl-tlb.h"
  55. #include "cl-except.h"
  56.  
  57.  
  58. #define END_OF_CYCLE     {                        \
  59.             (*steps)--;                    \
  60.             if (display) print_pipeline ();            \
  61.             continue;                    \
  62.             }
  63.  
  64. /* Imported functions: */
  65. #ifdef __STDC__
  66. long atol (const char *);
  67. #else
  68. long atol ();
  69. #endif
  70.  
  71.  
  72. /* Exported Variables: */
  73.  
  74. int cycle_level, cycle_running, cycle_steps;
  75. int EX_bp_reg, MEM_bp_reg, CP_bp_reg, CP_bp_cc, CP_bp_z;
  76. reg_word EX_bp_val, MEM_bp_val, CP_bp_val;
  77. int FP_add_cnt, FP_mul_cnt, FP_div_cnt;
  78. PIPE_STAGE alu[5] = {NULL, NULL, NULL, NULL, NULL};
  79. PIPE_STAGE fpa[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
  80.  
  81.  
  82. /* Local functions: */
  83.  
  84. #ifdef __STDC__
  85. static int cycle_spim (int *steps, int display);
  86. static int can_issue (short int oc);
  87. static int process_ID (PIPE_STAGE ps, int *stall, int mult_div_busy);
  88. static int process_EX (PIPE_STAGE ps, struct mult_div_unit *pMDU);
  89. static int process_MEM (PIPE_STAGE ps, MEM_SYSTEM mem_sys);
  90. static int process_WB (PIPE_STAGE ps);
  91. static int process_f_ex1 (PIPE_STAGE ps);
  92. static int process_f_ex2 (PIPE_STAGE ps);
  93. static int process_f_fwb (PIPE_STAGE ps);
  94. static void init_stage_pool (void);
  95. static PIPE_STAGE stage_alloc (void);
  96. static int stage_dealloc (PIPE_STAGE ps);
  97. static int pipe_dealloc (int stage, PIPE_STAGE alu[], PIPE_STAGE fpa[]);
  98. static void long_multiply (reg_word v1, reg_word v2, reg_word *hi, reg_word
  99.                *lo);
  100. #else
  101. static int cycle_spim ();
  102. static int can_issue ();
  103. static int process_ID ();
  104. static int process_EX ();
  105. static int process_MEM ();
  106. static int process_WB ();
  107. static int process_f_ex1 ();
  108. static int process_f_ex2 ();
  109. static int process_f_fwb ();
  110. static void init_stage_pool ();
  111. static PIPE_STAGE stage_alloc ();
  112. static int stage_dealloc ();
  113. static int pipe_dealloc ();
  114. static void long_multiply ();
  115. #endif
  116.  
  117.  
  118. /* local counters for collecting statistics */
  119. static int mem_stall_count;
  120. static int total_mem_ops;
  121.  
  122. static int bd_slot;
  123. struct mult_div_unit MDU;
  124.  
  125.  
  126.  
  127. /* function cl_run_program:
  128.  * responsible for calling cycle_spim; completes when <steps> cycles have
  129.  * been completed or when exception processing indicates that execution has
  130.  * paused or ended.
  131.  */
  132.  
  133. #ifdef __STDC__
  134. void
  135. cl_run_program (mem_addr addr, int steps, int display)
  136. #else
  137. void
  138. cl_run_program (addr, steps, display)
  139.   mem_addr addr;
  140.   int steps, display;
  141. #endif
  142. {
  143.   PC = addr;
  144.   cycle_steps = steps;
  145.   cycle_running = 1;
  146.  
  147.   while (cycle_steps > 0)
  148.     {
  149.       if (cycle_spim (&cycle_steps, display)) {
  150.  
  151.     switch (process_excpt ()) {
  152.  
  153.       /* exception processed ok, continue execution */
  154.     case 0:
  155.       cycle_init ();
  156.       break;
  157.  
  158.       /* exception processed ok, but stop execution */
  159.     case 1:
  160.       cycle_init ();
  161.       return;
  162.  
  163.       /* bad exception, signal, or exit; reinit for next time */
  164.     case -1:
  165.       PC = 0;
  166.       nPC = 0;
  167.       cycle_init ();
  168.       kill_prog_fds ();
  169.       cycle_running = 0;
  170.  
  171.       return;
  172.     }
  173.       }
  174.     }
  175. }
  176.  
  177.  
  178. /* for initialization of counting stuff and between runs of program */
  179.  
  180. #ifdef __STDC__
  181. void
  182. cl_initialize_world (int run)
  183. #else
  184. void
  185. cl_initialize_world (run)
  186.      int run;
  187. #endif
  188. {
  189.   initialize_registers ();
  190.   initialize_run_stack (0, 0);
  191.   initialize_catch_signals ();
  192.   if (cycle_level) {
  193.     if (run) 
  194.       initialize_prog_fds ();
  195.     initialize_sighandlers ();
  196.     initialize_excpt_counts ();
  197.     cycle_init ();
  198.     mdu_and_fp_init ();
  199.     tlb_init();
  200.     cache_init (mem_system, DATA_CACHE);
  201.     cache_init (mem_system, INST_CACHE);
  202.   }
  203. }
  204.  
  205.  
  206. /* cleanup after exceptions */
  207.  
  208. #ifdef __STDC__
  209. void
  210. cycle_init (void)
  211. #else
  212. void
  213. cycle_init ()
  214. #endif
  215. {
  216.   R[0] = 0;
  217.   EPC = 0;
  218.   Cause = 0;
  219.   bd_slot = FALSE;
  220.   bp_clear ();
  221.   pipe_dealloc (WB+1, alu, fpa);
  222.  
  223.   program_break = ((program_break / 32) + 1) * 32;
  224. }
  225.  
  226.  
  227. /* should be called when floating point and mdu unit are starting fresh */
  228.  
  229. #ifdef __STDC__
  230. void
  231. mdu_and_fp_init (void)
  232. #else
  233. void
  234. mdu_and_fp_init ()
  235. #endif
  236. {
  237.   MDU.count = 0;
  238.   FP_add_cnt = 0;
  239.   FP_mul_cnt = 0;
  240.   FP_div_cnt = 0;
  241.   FP_reg_present = 0xffffffff;
  242.   HI_present = 1;
  243.   LO_present = 1;
  244. }
  245.  
  246.  
  247.  
  248.  
  249. /* function cycle_spim:
  250.  * responsible for stepping through code until an exception occurs; returns
  251.  * 1 upon finding an exception, 0 upon completing number of steps.
  252.  */
  253.  
  254. #ifdef __STDC__
  255. static int
  256. cycle_spim (int *steps, int display)
  257. #else
  258. static int
  259. cycle_spim (steps, display)
  260.      int *steps, display;
  261. #endif
  262. {
  263.   PIPE_STAGE ps_ptr, fp_ptr, fp_prev;
  264.   mem_addr bus_req;
  265.   int id_stall = FALSE, mem_stall = FALSE, cmiss = 0;
  266.  
  267.   while (*steps > 0) {
  268.  
  269.     bus_req = bus_service (mem_system);
  270.  
  271.     /* increment Random register each cycle */
  272.     Random = (((Random >> 8) < 63) ? ((Random >> 8) + 1) : 8) << 8;
  273.     cmiss = 0;
  274.  
  275.     /* Service mult/div unit */
  276.     if (MDU.count == 1) {
  277.       MDU.count = 0;
  278.       HI_present = 1;
  279.       HI = MDU.hi_val;
  280.       LO_present = 1;
  281.       LO = MDU.lo_val;
  282.     }
  283.     else if (MDU.count > 1)
  284.       MDU.count--;
  285.  
  286.     /* service fpa unit available counts */
  287.     FP_add_cnt = ((FP_add_cnt == 0) ? 0 : FP_add_cnt - 1);
  288.     FP_mul_cnt = ((FP_mul_cnt == 0) ? 0 : FP_mul_cnt - 1);
  289.     FP_div_cnt = ((FP_div_cnt == 0) ? 0 : FP_div_cnt - 1);
  290.  
  291.  
  292.     /* Floating Point Write Back */
  293.     fp_ptr = fpa[FPA_FWB];
  294.     while (fp_ptr != NULL) {
  295.       PIPE_STAGE tmp_ptr;
  296.  
  297.       process_f_fwb(fp_ptr);
  298.       tmp_ptr = fp_ptr->next;
  299.       stage_dealloc(fp_ptr);
  300.       fp_ptr = tmp_ptr;
  301.     }
  302.  
  303.     fpa[FPA_FWB] = NULL;
  304.  
  305.  
  306.  
  307.     /* Write Back Stage */
  308.     ps_ptr = alu[WB];
  309.     if (ps_ptr != NULL) {
  310.  
  311.       if (EXCPT (ps_ptr) != 0) {
  312.     /* exception is about to be handled, set up registers */
  313.     Cause = EXCPT (ps_ptr);
  314.     if (DSLOT(ps_ptr)) Cause |= 0x80000000;
  315.     else Cause &= 0x7fffffff;
  316.     EPC = STAGE_PC(ps_ptr) - (DSLOT (ps_ptr) ? BYTES_PER_WORD : 0);
  317.     return (1);
  318.       }
  319.  
  320.       process_WB(ps_ptr);
  321.  
  322.       /* maintain invariant */
  323.       R[0] = 0;
  324.       stage_dealloc(ps_ptr);
  325.       alu[WB] = NULL;
  326.     }
  327.  
  328.  
  329.  
  330.     /* FPA WB stage -- there maybe up to 4 entries in this stage
  331.      * one for each of the functional units */
  332.     /* If an instruction gets this far, then all previous instructions
  333.      * will complete without causing an exception */
  334.     fp_ptr = fpa[FPA_EX3];
  335.     fp_prev = NULL;
  336.     while (fp_ptr != NULL) {
  337.       PIPE_STAGE tmp_ptr;
  338.  
  339.       process_f_ex2(fp_ptr);
  340.       /* This one is ready to go to wb if count is 0 */
  341.       if (Count (fp_ptr) == 0) {
  342.  
  343.     /* fix up list */
  344.     if (fp_prev == NULL)
  345.       fpa[FPA_EX3] = fp_ptr->next;
  346.     else
  347.       fp_prev->next = fp_ptr->next;
  348.  
  349.     tmp_ptr = fp_ptr->next;
  350.     fp_ptr->next = fpa[FPA_FWB];
  351.     fpa[FPA_FWB] = fp_ptr;
  352.     fp_ptr = tmp_ptr;
  353.       }
  354.       else { /* Count > 0 */
  355.     fp_prev = fp_ptr;
  356.     fp_ptr = fp_ptr->next;
  357.       }
  358.  
  359.     }
  360.  
  361.  
  362.  
  363.     /* FPA MEM stage */
  364.     /* Any FP exception will have already been signaled. */
  365.     fp_ptr = fpa[FPA_EX2];
  366.     if (fp_ptr != NULL) {
  367.       process_f_ex2(fp_ptr);
  368.       fp_ptr->next = fpa[FPA_EX3];
  369.       fpa[FPA_EX3] = fp_ptr;
  370.       fpa[FPA_EX2] = NULL;
  371.     }
  372.  
  373.  
  374.  
  375.     /* MEM STALL stage */
  376.     /* Cannot get to MEM STALL if an instruction earlier
  377.      * in the pipeline causes an exception. */
  378.     ps_ptr = alu[MEM];
  379.     if ((ps_ptr != NULL) && STAGE (ps_ptr) == MEM_STALL) {
  380.       if (RNUM (ps_ptr) == bus_req) {
  381.     if (((OPCODE (ps_ptr->inst) == Y_LWC1_OP) ||
  382.          (OPCODE (ps_ptr->inst) == Y_MTC1_OP))) {
  383.       ps_ptr->next = fpa[FPA_EX3];
  384.       fpa[FPA_EX3] = ps_ptr;
  385.       alu[MEM] = NULL;
  386.     }
  387.     else {
  388.       STAGE (ps_ptr) = WB;
  389.       alu[WB] = ps_ptr;
  390.       alu[MEM] = NULL;
  391.     }
  392.     mem_stall = FALSE;
  393.       }
  394.       else mem_stall = TRUE;
  395.     }
  396.  
  397.  
  398.  
  399.     /* MEM Stage */
  400.     ps_ptr = alu[MEM];
  401.     if ((ps_ptr != NULL) && (STAGE (ps_ptr) == MEM)) {
  402.  
  403.       /* use SWC2 to print memory stats */
  404.       if ((EXCPT(ps_ptr) == 0) && (OPCODE(ps_ptr->inst) == Y_SWC2_OP)) {
  405.     write_output (message_out, "memory system counts:\n");
  406.     write_output (message_out, "\t%d stalls, %d total memory ops.\n",
  407.               mem_stall_count, total_mem_ops);
  408.     stat_print();
  409.     fflush(stdout);
  410.       }
  411.  
  412.       else if (EXCPT (ps_ptr) == 0)
  413.     cmiss = process_MEM(ps_ptr, mem_system);
  414.  
  415.       if (EXCPT (ps_ptr) != 0) {
  416.     STAGE (ps_ptr) = WB;
  417.     alu[WB] = ps_ptr;
  418.     alu[MEM] = NULL;
  419.     pipe_dealloc(MEM, alu, fpa);
  420.     END_OF_CYCLE
  421.       }
  422.  
  423.       else if (cmiss == CACHE_MISS) {
  424.     STAGE (ps_ptr) = MEM_STALL;
  425.     mem_stall = TRUE;
  426.       }
  427.  
  428.       /* If this is a floating point load or a MTC1, move it to
  429.        * the floating point pipeline */
  430.       else if ((OPCODE (ps_ptr->inst) == Y_LWC1_OP) ||
  431.            (OPCODE (ps_ptr->inst) == Y_MTC1_OP)) {
  432.     ps_ptr->next = fpa[FPA_EX3];
  433.     fpa[FPA_EX3] = ps_ptr;
  434.     alu[MEM] = NULL;
  435.       }
  436.  
  437.       else {
  438.     STAGE (ps_ptr) = WB;
  439.     alu[WB] = ps_ptr;
  440.     alu[MEM] = NULL;
  441.       }
  442.   }
  443.  
  444.  
  445.  
  446.  
  447.     /* FPA EX Stage */
  448.     fp_ptr = fpa[FPA_EX1];
  449.     if (fp_ptr != NULL) {
  450.       process_f_ex1(fp_ptr);
  451.       fpa[FPA_EX2] = fp_ptr;
  452.       fpa[FPA_EX1] = NULL;
  453.       if (EXCPT (fp_ptr) != 0) {
  454.     pipe_dealloc(FPA_EX1, alu, fpa);
  455.     END_OF_CYCLE
  456.       }
  457.     }
  458.  
  459.  
  460.  
  461.     /* EX Stage */
  462.     ps_ptr = alu[EX];
  463.     if ((ps_ptr != NULL) && (! mem_stall)) {
  464.  
  465.       if (EXCPT (ps_ptr) == 0)
  466.     process_EX(ps_ptr, &(MDU));
  467.  
  468.       STAGE (ps_ptr) = MEM;
  469.       alu[MEM] = ps_ptr;
  470.       alu[EX] = NULL;
  471.  
  472.       if (EXCPT (ps_ptr) != 0) {
  473.     pipe_dealloc(EX, alu, fpa);
  474.     END_OF_CYCLE
  475.       }
  476.     }
  477.  
  478.  
  479.  
  480.     /* ID Stage */
  481.  
  482.     ps_ptr = alu[ID];
  483.     if ((ps_ptr != NULL) && (STAGE(ps_ptr) == ID) && !mem_stall) {
  484.       id_stall = FALSE;
  485.  
  486.       DSLOT(ps_ptr) = bd_slot;
  487.       if (EXCPT (ps_ptr) == 0) {
  488.     process_ID (ps_ptr, &id_stall, MDU.count);
  489.     if (!id_stall)
  490.       bd_slot = ((DSLOT(ps_ptr) == TRUE) ? FALSE :
  491.               (IS_BRANCH (OPCODE(ps_ptr->inst)) ? TRUE : FALSE));
  492.       }
  493.  
  494.       if (!id_stall) {
  495.     STAGE (ps_ptr) = EX;
  496.     /* If it's a floating point op move it to the floating point
  497.      * pipeline */
  498.     if ((EXCPT(ps_ptr) == 0) && (is_fp_op(OPCODE (ps_ptr->inst))))
  499.       fpa[FPA_EX1] = ps_ptr;
  500.     else
  501.       alu[EX] = ps_ptr;
  502.     alu[ID] = NULL;
  503.       }
  504.  
  505.       if (EXCPT (ps_ptr) != 0) {
  506.     pipe_dealloc(ID, alu, fpa);
  507.     END_OF_CYCLE
  508.       }
  509.     }
  510.  
  511.  
  512.  
  513.  
  514.     /* IF STALL stage */
  515.     ps_ptr = alu[IF];
  516.     if ((ps_ptr != NULL) && (STAGE (ps_ptr) == IF_STALL)) {
  517.       if (RNUM (ps_ptr) == bus_req)
  518.     if (mem_stall || id_stall) {
  519.       STAGE(ps_ptr) = IF;
  520.       END_OF_CYCLE
  521.     }
  522.     else {
  523.       STAGE (ps_ptr) = ID;
  524.       alu[ID] = ps_ptr;
  525.       alu[IF] = NULL;
  526.       PC = (nPC ? nPC : PC + BYTES_PER_WORD);
  527.     }
  528.       else END_OF_CYCLE
  529.     }
  530.  
  531.  
  532.     /* IF Stage */
  533.     else if (ps_ptr != NULL && (STAGE(ps_ptr) == IF))  {
  534.       CL_READ_MEM_INST(mem_system, ps_ptr->inst, STAGE_PC(ps_ptr),
  535.                PADDR(ps_ptr), cmiss, EXCPT(ps_ptr), RNUM(ps_ptr))
  536.  
  537.       /* reinsert a breakpoint (occurs only after break excpt was caught) */
  538.       if (STAGE_PC(ps_ptr) == breakpoint_reinsert) {
  539.     add_breakpoint (STAGE_PC(ps_ptr));
  540.     breakpoint_reinsert = 0;
  541.       }
  542.  
  543.       /* if exception, must be tlb, read instruction for viewing purposes */
  544.       if (EXCPT(ps_ptr) != 0) {
  545.     if (! (mem_stall || id_stall)) {
  546.       alu[ID] = ps_ptr;
  547.       alu[IF] = NULL;
  548.       STAGE (ps_ptr) = ID;
  549.       PC = (nPC ? nPC : PC + BYTES_PER_WORD);
  550.     }
  551.     END_OF_CYCLE
  552.       }
  553.  
  554.       else if (cmiss == CACHE_MISS) {
  555.     STAGE (ps_ptr) = IF_STALL;
  556.     END_OF_CYCLE
  557.     }
  558.  
  559.       else if (mem_stall || id_stall)
  560.     END_OF_CYCLE
  561.  
  562.       else {
  563.     alu[ID] = ps_ptr;
  564.     alu[IF] = NULL;
  565.     STAGE (ps_ptr) = ID;
  566.     PC = (nPC ? nPC : PC + BYTES_PER_WORD);
  567.       }
  568.     }
  569.  
  570.  
  571.     /* if we got this far, get next instruction into IF stage */
  572.     alu[IF] = stage_alloc();
  573.     STAGE (alu[IF]) = IF;
  574.     STAGE_PC (alu[IF]) = PC;
  575.     /* do a dummy read just so we can see the instruction in the pipeline */
  576.     READ_MEM_INST (alu[IF]->inst, PC);
  577.  
  578.     END_OF_CYCLE
  579.  
  580.   }
  581.   return 0;
  582. }
  583.  
  584.  
  585. #ifdef __STDC__
  586. static int
  587. can_issue (short int oc)
  588. #else
  589. static int
  590. can_issue (oc)
  591.      short oc;
  592. #endif
  593. {
  594.   /* Can't issue anything if the adder is busy or about to be busy */
  595.   if ((FP_add_cnt > 0) || (FP_mul_cnt == 1) || ((FP_div_cnt <= 3) && (FP_div_cnt > 0)))
  596.     return(0);
  597.  
  598.   switch (oc)
  599.     {
  600.     case Y_ADD_S_OP:
  601.     case Y_ADD_D_OP:
  602.     case Y_CVT_S_D_OP:
  603.     case Y_CVT_W_D_OP:
  604.     case Y_CVT_W_S_OP:
  605.     case Y_SUB_S_OP:
  606.     case Y_SUB_D_OP:
  607.       /* Need adder for 2 cycles.  First one is already known
  608.      to be free.  As long as mul_cnt > 2 or = 0, and div_cnt > 4 or = 0
  609.      ok */
  610.       return (((FP_mul_cnt == 0) || (FP_mul_cnt > 2)) &&
  611.           ((FP_div_cnt == 0) || (FP_div_cnt > 4)));
  612.       break;
  613.  
  614.     case Y_CVT_D_W_OP:
  615.     case Y_CVT_S_W_OP:
  616.       /* Need adder for 3 cycles.  First one is already known
  617.      to be free.  As long as mul_cnt > 3, and div_cnt > 5
  618.      ok */
  619.       return (((FP_mul_cnt == 0) || (FP_mul_cnt > 2)) &&
  620.           ((FP_div_cnt == 0) || (FP_div_cnt > 4)));
  621.  
  622.     case Y_DIV_S_OP:
  623.     case Y_DIV_D_OP:
  624.       /* Need adder for 3 cycles in > 8 cycles.  If there is
  625.       an outstanding multiply it must be finished before then. */
  626.       return (FP_div_cnt == 0); break;
  627.  
  628.     case Y_MUL_S_OP:
  629.       /* Need adder for 1 cycle in 2 cycles.  */
  630.       return ((FP_mul_cnt == 0) &&
  631.           ((FP_div_cnt > 2) || (FP_div_cnt == 0)));
  632.  
  633.       case Y_MUL_D_OP:
  634.       /* Need adder for 1 cycle in 3 cycles */
  635.       return ((FP_mul_cnt == 0) && ((FP_div_cnt > 3) || (FP_div_cnt == 0)));
  636.       break;
  637.  
  638.     default:
  639.       return (1);
  640.       break;
  641.     }
  642. }
  643.  
  644.  
  645. #define stall2(op, r1, r2)                         \
  646.   (!(can_issue((op)) && is_present((r1)) && is_present ((r2))))
  647.  
  648. #define stall3(op, r1, r2, r3)                         \
  649.   (!(can_issue((op)) && is_present((r1)) && is_present ((r2))         \
  650.      && is_present((r3))))
  651.  
  652.  
  653.  
  654.  
  655. /* simulate ID stage */
  656. /* must process WB stage before this one to make sure the right values
  657.    are available */
  658.  
  659. /* Branches in the delay slot are treated as Nops.  */
  660. #ifdef __STDC__
  661. static int
  662. process_ID (PIPE_STAGE ps, int *stall, int mult_div_busy)
  663. #else
  664. static int
  665. process_ID (ps, stall, mult_div_busy)
  666.   PIPE_STAGE ps;
  667.   int *stall, mult_div_busy;
  668. #endif
  669. {
  670.   instruction *inst;
  671.   mem_addr tmp_PC;
  672.   int excpt = -1;
  673.  
  674.   inst = ps->inst;
  675.   tmp_PC = PC + BYTES_PER_WORD;
  676.  
  677.   switch (OPCODE (inst))
  678.     {
  679.     case Y_ADD_OP:
  680.       Operand1 (ps) = read_R_reg(RS (inst));
  681.       Operand2 (ps) = read_R_reg(RT (inst));
  682.       break;
  683.  
  684.  
  685.     case Y_ADDI_OP:
  686.       Operand1 (ps) = read_R_reg(RS (inst));
  687.       Operand2 (ps) = IMM (inst);
  688.  
  689.     case Y_ADDIU_OP:
  690.       Operand1 (ps) = read_R_reg(RS (inst));
  691.       Operand2 (ps) = IMM (inst);
  692.       break;
  693.  
  694.     case Y_ADDU_OP:
  695.       Operand1 (ps) = read_R_reg(RS (inst));
  696.       Operand2 (ps) = read_R_reg(RT (inst));
  697.       break;
  698.  
  699.     case Y_AND_OP:
  700.       Operand1 (ps) = read_R_reg(RS (inst));
  701.       Operand2 (ps) = read_R_reg(RT (inst));
  702.       break;
  703.  
  704.     case Y_ANDI_OP:
  705.       Operand1 (ps) = read_R_reg(RS (inst));
  706.       Operand2 (ps) = IMM (inst);
  707.       break;
  708.  
  709.     case Y_BC0F_OP:
  710.     case Y_BC2F_OP:
  711.     case Y_BC3F_OP:
  712.       if (!DSLOT(ps))
  713.     /* arg to COP_Available divided by two to find which coprocessor, */
  714.     /* see opcode table in y.tab.c */
  715.     if (!COP_Available( (OPCODE (inst) - Y_BC0F_OP)/2 ))
  716.       CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE(inst)-Y_BC0F_OP)/2, EXCPT (ps))
  717.     else if (CpCond[(OPCODE (inst) - Y_BC0F_OP)/2] == 0)
  718.       tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  719.       break;
  720.  
  721.     case Y_BC1F_OP:
  722.       if (!DSLOT(ps))
  723.     if (!COP_Available( (OPCODE (inst) - Y_BC0F_OP)/2 ))
  724.       CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE(inst)-Y_BC0F_OP)/2, EXCPT(ps))
  725.     else if (FpCond == 0)
  726.       tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  727.       break;
  728.  
  729.  
  730.     case Y_BC0T_OP:
  731.     case Y_BC2T_OP:
  732.     case Y_BC3T_OP:
  733.       if (!DSLOT(ps)) {
  734.     if (!COP_Available( (OPCODE (inst) - Y_BC0T_OP)/2 ))
  735.       CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE(inst)-Y_BC0T_OP)/2, EXCPT(ps))
  736.     else if (CpCond[(OPCODE (inst) - Y_BC0T_OP)/2] != 0)
  737.       tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  738.       }
  739.       break;
  740.  
  741.     case Y_BC1T_OP:
  742.       if (!DSLOT(ps)) {
  743.     if (!COP_Available( (OPCODE (inst) - Y_BC0T_OP)/2 ))
  744.       CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE(inst)-Y_BC0T_OP)/2, EXCPT(ps))
  745.     else if (FpCond != 0)
  746.       tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  747.       }
  748.       break;
  749.  
  750.     case Y_BEQ_OP:
  751.       if (!DSLOT(ps) &&  (read_R_reg(RS (inst)) == read_R_reg(RT (inst))))
  752.       tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  753.       break;
  754.  
  755.     case Y_BGEZ_OP:
  756.       if (!DSLOT(ps) && (SIGN_BIT (read_R_reg(RS (inst))) == 0))
  757.     tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  758.       break;
  759.  
  760.     case Y_BGEZAL_OP:
  761.       if (!DSLOT(ps) && (SIGN_BIT (read_R_reg(RS (inst))) == 0))
  762.     tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  763.       break;
  764.  
  765.     case Y_BGTZ_OP:
  766.       if ((!DSLOT(ps)) &&
  767.       (read_R_reg(RS (inst)) != 0 && SIGN_BIT (read_R_reg(RS (inst))) == 0))
  768.     tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  769.       break;
  770.  
  771.     case Y_BLEZ_OP:
  772.       if ((!DSLOT(ps)) &&
  773.       (read_R_reg(RS (inst)) == 0 || SIGN_BIT (read_R_reg(RS (inst))) != 0))
  774.     tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  775.       break;
  776.  
  777.     case Y_BLTZ_OP:
  778.       if ((!DSLOT(ps)) &&
  779.       (SIGN_BIT (read_R_reg(RS (inst))) != 0))
  780.     tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  781.       break;
  782.  
  783.     case Y_BLTZAL_OP:
  784.       if ((!DSLOT(ps)) &&
  785.       (SIGN_BIT (read_R_reg(RS (inst))) != 0))
  786.     tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  787.       break;
  788.  
  789.     case Y_BNE_OP:
  790.       if ((!DSLOT(ps)) &&
  791.       (read_R_reg(RS (inst)) != read_R_reg(RT (inst))))
  792.     tmp_PC = PC + (SIGN_EX (IOFFSET (inst)) << 2);
  793.       break;
  794.  
  795.     case Y_BREAK_OP:
  796.       CL_RAISE_EXCEPTION(BKPT_EXCPT, 0, EXCPT(ps));
  797.       break;
  798.  
  799.     case Y_CFC0_OP:
  800.     case Y_CFC2_OP:
  801.     case Y_CFC3_OP:
  802.       if (!COP_Available(OPCODE (inst) - Y_CFC0_OP))
  803.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_CFC0_OP) , EXCPT(ps));
  804.       Operand1 (ps) = read_CP_reg((OPCODE (inst) - Y_CFC0_OP), RD (inst), 0);
  805.       break;
  806.  
  807.     case Y_COP0_OP:
  808.     case Y_COP1_OP:
  809.     case Y_COP2_OP:
  810.     case Y_COP3_OP:
  811.       if (!COP_Available(OPCODE (inst) - Y_COP0_OP))
  812.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_COP0_OP) , EXCPT(ps));
  813.       Operand2 (ps) = read_R_reg(RT (inst));
  814.       break;
  815.  
  816.     case Y_CTC0_OP:
  817.     case Y_CTC2_OP:
  818.     case Y_CTC3_OP:
  819.       if (!COP_Available(OPCODE (inst) - Y_CTC0_OP))
  820.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_CTC0_OP) , EXCPT(ps));
  821.       Operand2 (ps) = read_R_reg(RT (inst));
  822.       break;
  823.  
  824.     case Y_DIV_OP:
  825.     case Y_DIVU_OP:
  826.       if (mult_div_busy)
  827.     *stall = 1;
  828.       else {
  829.     Operand1 (ps) = read_R_reg(RS (inst));
  830.     Operand2 (ps) = read_R_reg(RT (inst));
  831.       }
  832.       break;
  833.  
  834.     case Y_J_OP:
  835.       if (!DSLOT (ps))
  836.     tmp_PC = ((PC & 0xf0000000) | (TARGET (inst) & 0x03ffffff) << 2);
  837.       break;
  838.  
  839.     case Y_JAL_OP:
  840.       if (!DSLOT (ps))
  841.     tmp_PC = ((PC & 0xf0000000) | ((TARGET (inst) & 0x03ffffff) << 2));
  842.       break;
  843.  
  844.     case Y_JALR_OP:
  845.     case Y_JR_OP:
  846.       if (!DSLOT (ps))
  847.     tmp_PC = read_R_reg(RS (inst));
  848.       break;
  849.  
  850.     case Y_LB_OP:
  851.     case Y_LBU_OP:
  852.     case Y_LH_OP:
  853.     case Y_LHU_OP:
  854.     case Y_LW_OP:
  855.     case Y_LWL_OP:
  856.     case Y_LWR_OP:
  857.       Operand1 (ps) = read_R_reg(BASE (inst));
  858.       Operand2 (ps) = IOFFSET (inst);
  859.       break;
  860.  
  861.     case Y_LWC0_OP:
  862.     case Y_LWC2_OP:
  863.     case Y_LWC3_OP:
  864.       if (!COP_Available(OPCODE (inst) - Y_LWC0_OP))
  865.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_LWC0_OP) , EXCPT(ps));
  866.       Operand1 (ps) = read_R_reg(BASE (inst));
  867.       Operand2 (ps) = IOFFSET (inst);
  868.       break;
  869.  
  870.     case Y_LUI_OP:
  871.       Operand2 (ps) = IMM (inst);
  872.       break;
  873.  
  874.     case Y_MFC0_OP:
  875.     case Y_MFC2_OP:
  876.     case Y_MFC3_OP:
  877.       if (!COP_Available(OPCODE (inst) - Y_MFC0_OP))
  878.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_MFC0_OP), EXCPT(ps));
  879.       Operand1 (ps) = read_CP_reg((OPCODE (inst) - Y_MFC0_OP), RD (inst), 1);
  880.       break;
  881.  
  882.     case Y_MFHI_OP:
  883.       if (HI_present)
  884.     Operand1 (ps) = HI;
  885.       else
  886.     *stall = 1;
  887.       break;
  888.  
  889.     case Y_MFLO_OP:
  890.       if (LO_present)
  891.     Operand1 (ps) = LO;
  892.       else
  893.     *stall = 1;
  894.       break;
  895.  
  896.     case Y_MTC0_OP:
  897.     case Y_MTC2_OP:
  898.     case Y_MTC3_OP:
  899.       if (!COP_Available(OPCODE (inst) - Y_MTC0_OP))
  900.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_MTC0_OP), EXCPT(ps));
  901.       Operand2 (ps) = read_R_reg(RT (inst));
  902.       break;
  903.  
  904.     case Y_MTC1_OP:
  905.       if (!COP_Available(OPCODE (inst) - Y_MTC0_OP))
  906.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_MTC0_OP), EXCPT(ps));
  907.       Operand2 (ps) = read_R_reg(RT (inst));
  908.       *stall = ! (is_present(RD (inst)));
  909.       clr_single_present(RD (inst));
  910.       break;
  911.  
  912.  
  913.     case Y_MTHI_OP:
  914.     case Y_MTLO_OP:
  915.       Operand1 (ps) = read_R_reg(RS (inst));
  916.       break;
  917.  
  918.     case Y_MULT_OP:
  919.     case Y_MULTU_OP:
  920.       if (mult_div_busy)
  921.     *stall = 1;
  922.       else {
  923.     Operand1 (ps) = read_R_reg(RS (inst));
  924.     Operand2 (ps) = read_R_reg(RT (inst));
  925.       }
  926.       break;
  927.  
  928.     case Y_NOR_OP:
  929.     case Y_OR_OP:
  930.       Operand1 (ps) = read_R_reg(RS (inst));
  931.       Operand2 (ps) = read_R_reg(RT (inst));
  932.       break;
  933.  
  934.     case Y_ORI_OP:
  935.       Operand1 (ps) = read_R_reg(RS (inst));
  936.       Operand2 (ps) = IMM (inst);
  937.       break;
  938.  
  939.  
  940.     case Y_RFE_OP:
  941.       if (!COP_Available(0))
  942.     CL_RAISE_EXCEPTION(CPU_EXCPT, 0x0 , EXCPT(ps));
  943.       Operand1 (ps) = (Status_Reg & 0xfffffff0);
  944.       Operand2 (ps) = ((Status_Reg & 0x3c) >> 2);
  945.       break;
  946.  
  947.     case Y_SB_OP:
  948.     case Y_SH_OP:
  949.       Operand1 (ps) = read_R_reg(RT (inst));
  950.       Operand2 (ps) = read_R_reg(BASE (inst));
  951.       Operand3 (ps) = IOFFSET (inst);
  952.       break;
  953.  
  954.     case Y_SLL_OP:
  955.       Operand2 (ps) = read_R_reg(RT (inst));
  956.       break;
  957.  
  958.     case Y_SLLV_OP:
  959.       Operand1 (ps) = read_R_reg(RS (inst));
  960.       Operand2 (ps) =  0x1f;
  961.  
  962.     case Y_SLT_OP:
  963.       Operand1 (ps) = read_R_reg(RS (inst));
  964.       Operand2 (ps) = read_R_reg(RT (inst));
  965.       break;
  966.  
  967.     case Y_SLTI_OP:
  968.     case Y_SLTIU_OP:
  969.       Operand1 (ps) = read_R_reg(RS (inst));
  970.       Operand2 (ps) = IMM (inst);
  971.       break;
  972.  
  973.  
  974.     case Y_SLTU_OP:
  975.       Operand1 (ps) = read_R_reg(RS (inst));
  976.       Operand2 (ps) = read_R_reg(RT (inst));
  977.       break;
  978.  
  979.     case Y_SRA_OP:
  980.       Operand2 (ps) = read_R_reg(RT (inst));
  981.       break;
  982.  
  983.     case Y_SRAV_OP:
  984.       Operand1 (ps) = read_R_reg(RS (inst));
  985.       Operand2 (ps) = read_R_reg(RT (inst));
  986.       break;
  987.  
  988.     case Y_SRL_OP:
  989.       Operand2 (ps) = read_R_reg(RT (inst));
  990.       break;
  991.  
  992.     case Y_SRLV_OP:
  993.     case Y_SUB_OP:
  994.     case Y_SUBU_OP:
  995.       Operand1 (ps) = read_R_reg(RS (inst));
  996.       Operand2 (ps) = read_R_reg(RT (inst));
  997.       break;
  998.  
  999.     case Y_SW_OP:
  1000.     case Y_SWL_OP:
  1001.     case Y_SWR_OP:
  1002.       Operand1 (ps) = read_R_reg(RT (inst));
  1003.       Operand2 (ps) = read_R_reg(BASE (inst));
  1004.       Operand3 (ps) = IOFFSET (inst);
  1005.       break;
  1006.  
  1007.     case Y_SWC1_OP:
  1008.       if (!COP_Available(OPCODE (inst) - Y_SWC0_OP))
  1009.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_SWC0_OP), EXCPT(ps));
  1010.       Operand2 (ps) = read_R_reg(BASE (inst));
  1011.       Operand3 (ps) = IOFFSET (inst);
  1012.  
  1013.       *stall = !is_single_present(RT (inst));
  1014.       break;
  1015.  
  1016.     case Y_SWC0_OP:
  1017.     case Y_SWC3_OP:
  1018.       if (!COP_Available(OPCODE (inst) - Y_SWC0_OP))
  1019.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_SWC0_OP), EXCPT(ps));
  1020.       Operand1 (ps) = read_CP_reg((OPCODE (inst) - Y_SWC0_OP), RT (inst), 1);
  1021.       Operand2 (ps) = read_R_reg(BASE (inst));
  1022.       Operand3 (ps) = IOFFSET (inst);
  1023.       break;
  1024.  
  1025.     case Y_SWC2_OP:
  1026.       /* do nothing, SWC2 is being used to print memory stats */
  1027.       break;
  1028.  
  1029.     case Y_SYSCALL_OP:
  1030.       CL_RAISE_EXCEPTION(SYSCALL_EXCPT, 0, EXCPT(ps));
  1031.       break;
  1032.  
  1033.     case Y_TLBP_OP:
  1034.     case Y_TLBR_OP:
  1035.     case Y_TLBWI_OP:
  1036.     case Y_TLBWR_OP:
  1037.       if (!COP_Available(0))
  1038.     CL_RAISE_EXCEPTION(CPU_EXCPT, 0, EXCPT(ps));
  1039.       break;
  1040.  
  1041.     case Y_XOR_OP:
  1042.       Operand1 (ps) = read_R_reg(RS (inst));
  1043.       Operand2 (ps) = read_R_reg(RT (inst));
  1044.       break;
  1045.  
  1046.     case Y_XORI_OP:
  1047.       Operand1 (ps) = read_R_reg(RS (inst));
  1048.       Operand2 (ps) = IMM (inst);
  1049.       break;
  1050.  
  1051.     /* Floating point operations */
  1052.     case Y_ABS_S_OP:
  1053.       FPoperand1 (ps) = FPR_S (FS (inst));
  1054.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1055.       break;
  1056.  
  1057.  
  1058.     case Y_ABS_D_OP:
  1059.       FPoperand1 (ps) = FPR_D (FS (inst));
  1060.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1061.       break;
  1062.  
  1063.     case Y_ADD_S_OP:
  1064.       FPoperand1 (ps) = FPR_S (FS (inst));
  1065.       FPoperand2 (ps) = FPR_S (FT (inst));
  1066.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1067.       break;
  1068.  
  1069.     case Y_ADD_D_OP:
  1070.       FPoperand1 (ps) = FPR_D (FS (inst));
  1071.       FPoperand2 (ps) = FPR_D (FT (inst));
  1072.       *stall = stall3(OPCODE (inst), FS (inst), FT(inst), FD (inst));
  1073.       break;
  1074.  
  1075.  
  1076.     case Y_C_F_S_OP:
  1077.     case Y_C_UN_S_OP:
  1078.     case Y_C_EQ_S_OP:
  1079.     case Y_C_UEQ_S_OP:
  1080.     case Y_C_OLE_S_OP:
  1081.     case Y_C_ULE_S_OP:
  1082.     case Y_C_SF_S_OP:
  1083.     case Y_C_NGLE_S_OP:
  1084.     case Y_C_SEQ_S_OP:
  1085.     case Y_C_NGL_S_OP:
  1086.     case Y_C_LT_S_OP:
  1087.     case Y_C_NGE_S_OP:
  1088.     case Y_C_LE_S_OP:
  1089.     case Y_C_NGT_S_OP:
  1090.       FPoperand1 (ps) = FPR_S (FS (inst));
  1091.       FPoperand2 (ps) = FPR_S (FT (inst));
  1092.       *stall = stall2(OPCODE (inst), FS (inst), FT (inst));
  1093.       break;
  1094.  
  1095.  
  1096.     case Y_C_F_D_OP:
  1097.     case Y_C_UN_D_OP:
  1098.     case Y_C_EQ_D_OP:
  1099.     case Y_C_UEQ_D_OP:
  1100.     case Y_C_OLE_D_OP:
  1101.     case Y_C_ULE_D_OP:
  1102.     case Y_C_SF_D_OP:
  1103.     case Y_C_NGLE_D_OP:
  1104.     case Y_C_SEQ_D_OP:
  1105.     case Y_C_NGL_D_OP:
  1106.     case Y_C_LT_D_OP:
  1107.     case Y_C_NGE_D_OP:
  1108.     case Y_C_LE_D_OP:
  1109.     case Y_C_NGT_D_OP:
  1110.       FPoperand1 (ps) = FPR_D (FS (inst));
  1111.       FPoperand2 (ps) = FPR_D (FT (inst));
  1112.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1113.       break;
  1114.  
  1115.     case Y_CFC1_OP:
  1116.       /* What to do */
  1117.       break;
  1118.  
  1119.     case Y_CTC1_OP:
  1120.       /* What to do */
  1121.       break;
  1122.  
  1123.     case Y_CVT_D_S_OP:
  1124.       FPoperand1 (ps) = FPR_S (FS (inst));
  1125.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1126.       break;
  1127.  
  1128.     case Y_CVT_D_W_OP:
  1129.       FPoperand1 (ps) = FPR_W (FS (inst));
  1130.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1131.       break;
  1132.  
  1133.     case Y_CVT_S_D_OP:
  1134.       FPoperand1 (ps) = FPR_D (FS (inst));
  1135.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1136.       break;
  1137.  
  1138.  
  1139.     case Y_CVT_S_W_OP:
  1140.       FPoperand1 (ps) = FPR_W (FS (inst));
  1141.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1142.       break;
  1143.  
  1144.     case Y_CVT_W_D_OP:
  1145.       FPoperand1 (ps) = FPR_D (FS (inst));
  1146.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1147.       break;
  1148.  
  1149.  
  1150.     case Y_CVT_W_S_OP:
  1151.       FPoperand1 (ps) = FPR_S (FS (inst));
  1152.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1153.       break;
  1154.  
  1155.     case Y_DIV_S_OP:
  1156.       FPoperand1 (ps) = FPR_S (FS (inst));
  1157.       FPoperand2 (ps) = FPR_S (FT (inst));
  1158.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1159.       break;
  1160.  
  1161.     case Y_DIV_D_OP:
  1162.       FPoperand1 (ps) = FPR_D (FS (inst));
  1163.       FPoperand2 (ps) = FPR_D (FT (inst));
  1164.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1165.       break;
  1166.  
  1167.  
  1168.     case Y_LWC1_OP:
  1169.       if (!COP_Available(OPCODE (inst) - Y_LWC0_OP))
  1170.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_LWC0_OP) , EXCPT(ps));
  1171.       Operand1 (ps) = read_R_reg(BASE (inst));
  1172.       Operand2 (ps) = IOFFSET (inst);
  1173.       /* can't issue the load if some instruction in the floating
  1174.      point-pipeline is going to write to the dest */
  1175.       *stall = ! is_single_present(FT (inst));
  1176.       break;
  1177.  
  1178.     case Y_MFC1_OP:
  1179.       if (!COP_Available(OPCODE (inst) - Y_MFC0_OP))
  1180.     CL_RAISE_EXCEPTION(CPU_EXCPT, (OPCODE (inst) - Y_MFC0_OP), EXCPT(ps));
  1181.       *stall = ! (is_single_present (RD (inst)));
  1182.       break;
  1183.  
  1184.     case Y_MOV_S_OP:
  1185.       FPoperand1 (ps) = FPR_S (FS (inst));
  1186.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1187.       break;
  1188.  
  1189.  
  1190.     case Y_MOV_D_OP:
  1191.       FPoperand1 (ps) = FPR_D (FS (inst));
  1192.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1193.        break;
  1194.  
  1195.     case Y_MUL_S_OP:
  1196.       FPoperand1 (ps) = FPR_S (FS (inst));
  1197.       FPoperand2 (ps) = FPR_S (FT (inst));
  1198.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1199.       break;
  1200.  
  1201.  
  1202.     case Y_MUL_D_OP:
  1203.       FPoperand1 (ps) = FPR_D (FS (inst));
  1204.       FPoperand2 (ps) = FPR_D (FT (inst));
  1205.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1206.       break;
  1207.  
  1208.     case Y_NEG_S_OP:
  1209.       FPoperand1 (ps) = FPR_S (FS (inst));
  1210.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1211.       break;
  1212.  
  1213.  
  1214.     case Y_NEG_D_OP:
  1215.       FPoperand1 (ps) = FPR_D (FS (inst));
  1216.       *stall = stall2(OPCODE (inst), FS (inst), FD (inst));
  1217.       break;
  1218.  
  1219.  
  1220.     case Y_SUB_S_OP:
  1221.       FPoperand1 (ps) = FPR_S (FS (inst));
  1222.       FPoperand2 (ps) = FPR_S (FT (inst));
  1223.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1224.       break;
  1225.  
  1226.  
  1227.     case Y_SUB_D_OP:
  1228.       FPoperand1 (ps)  = FPR_D (FS (inst));
  1229.       FPoperand2 (ps) = FPR_D (FT (inst));
  1230.       *stall = stall3(OPCODE (inst), FS (inst), FT (inst), FD (inst));
  1231.       break;
  1232.  
  1233.  
  1234.     default:
  1235.       excpt = RI_EXCPT << 2;
  1236.       *stall = 0;
  1237.       break;
  1238.     }
  1239.  
  1240.   if (*stall == 0) {
  1241.     nPC = tmp_PC;
  1242.   }
  1243.  
  1244.   return (excpt);
  1245.  
  1246. }
  1247.  
  1248.  
  1249.  
  1250.  
  1251. /* Simulate EX stage */
  1252. /* integer unit only */
  1253. /* where do bypass values get set? */
  1254. /* Goal of EX to to compute value or address and to set the
  1255.    necessary bypass values. */
  1256.  
  1257. #ifdef __STDC__
  1258. static int
  1259. process_EX (PIPE_STAGE ps, struct mult_div_unit *pMDU)
  1260. #else
  1261. static int
  1262. process_EX (ps, pMDU)
  1263.      PIPE_STAGE ps;
  1264.      struct mult_div_unit *pMDU;
  1265. #endif
  1266. {
  1267.   instruction *inst;
  1268.  
  1269.   inst = ps->inst;
  1270.  
  1271.   switch (OPCODE (inst))
  1272.     {
  1273.     case Y_ADD_OP:
  1274.       {    register reg_word vs, vt;
  1275.     register reg_word sum;
  1276.  
  1277.     vs = Operand1 (ps);
  1278.     vt = Operand2 (ps);
  1279.     sum = vs + vt;
  1280.  
  1281.     if (ARITH_OVFL (sum, vs, vt))
  1282.       CL_RAISE_EXCEPTION (OVF_EXCPT, 0, EXCPT(ps));
  1283.  
  1284.     VALUE (ps) = sum;
  1285.     set_ex_bypass(RD (inst), sum);
  1286.     break;
  1287.       }
  1288.  
  1289.     case Y_ADDI_OP:
  1290.       {    register reg_word vs, imm;
  1291.     register reg_word sum;
  1292.  
  1293.     vs = Operand1 (ps);
  1294.     imm = (short) Operand2 (ps);
  1295.     sum = vs + imm;
  1296.  
  1297.     if (ARITH_OVFL (sum, vs, imm))
  1298.       CL_RAISE_EXCEPTION (OVF_EXCPT, 0, EXCPT(ps));
  1299.     VALUE (ps) = sum;
  1300.     set_ex_bypass(RT (inst), sum);
  1301.     break;
  1302.       }
  1303.  
  1304.     case Y_ADDIU_OP:
  1305.       VALUE (ps) = Operand1 (ps) + (short) Operand2 (ps);
  1306.       set_ex_bypass(RT (inst), VALUE (ps));
  1307.       break;
  1308.  
  1309.     case Y_ADDU_OP:
  1310.       VALUE (ps) = Operand1 (ps) + Operand2 (ps);
  1311.       set_ex_bypass(RD (inst), VALUE (ps));
  1312.       break;
  1313.  
  1314.     case Y_AND_OP:
  1315.       VALUE (ps) = Operand1 (ps) & Operand2 (ps);
  1316.       set_ex_bypass(RD (inst), VALUE (ps));
  1317.       break;
  1318.  
  1319.     case Y_ANDI_OP:
  1320.       /* why is the 0xffff necessary? */
  1321.       VALUE (ps) = Operand1 (ps) & (0xffff & Operand2 (ps));
  1322.       set_ex_bypass(RT (inst), VALUE (ps));
  1323.       break;
  1324.  
  1325.     case Y_BC0F_OP:
  1326.     case Y_BC1F_OP:
  1327.     case Y_BC2F_OP:
  1328.     case Y_BC3F_OP:
  1329.     case Y_BC0T_OP:
  1330.     case Y_BC1T_OP:
  1331.     case Y_BC2T_OP:
  1332.     case Y_BC3T_OP:
  1333.     case Y_BEQ_OP:
  1334.     case Y_BGEZ_OP:
  1335.       set_ex_bypass(0, 0);
  1336.       break;
  1337.  
  1338.     case Y_BGEZAL_OP:
  1339.       VALUE (ps) = STAGE_PC(ps) + 2 * BYTES_PER_WORD;
  1340.       /* where is the link value computed and stored?  should it be
  1341.      available through bypass?  */
  1342.       set_ex_bypass(31, VALUE (ps));
  1343.       break;
  1344.  
  1345.     case Y_BGTZ_OP:
  1346.     case Y_BLEZ_OP:
  1347.     case Y_BLTZ_OP:
  1348.       set_ex_bypass(0, 0);
  1349.       break;
  1350.  
  1351.     case Y_BLTZAL_OP:
  1352.       VALUE (ps) = STAGE_PC(ps) + 2 * BYTES_PER_WORD;
  1353.       set_ex_bypass(31, VALUE (ps));
  1354.       break;
  1355.  
  1356.     case Y_BNE_OP:
  1357.       set_ex_bypass(0, 0);
  1358.       break;
  1359.  
  1360.     case Y_BREAK_OP:
  1361.       /* what to do? */
  1362.       break;
  1363.  
  1364.     case Y_CFC0_OP:
  1365.     case Y_CFC2_OP:
  1366.     case Y_CFC3_OP:
  1367.       VALUE (ps) = Operand1 (ps);
  1368.       set_ex_bypass(0, 0);
  1369.       break;
  1370.  
  1371.     case Y_COP0_OP:
  1372.     case Y_COP1_OP:
  1373.     case Y_COP2_OP:
  1374.     case Y_COP3_OP:
  1375.       VALUE (ps) = Operand2 (ps);
  1376.       /* bypass? */
  1377.       set_ex_bypass(0, 0);
  1378.       break;
  1379.  
  1380.     case Y_CTC0_OP:
  1381.     case Y_CTC2_OP:
  1382.     case Y_CTC3_OP:
  1383.       VALUE (ps) = Operand2 (ps);
  1384.       /* bypass? */
  1385.       set_ex_bypass(0, 0);
  1386.       break;
  1387.  
  1388.     case Y_DIV_OP:
  1389.       { reg_word hi, lo;
  1390.  
  1391.     if (Operand2 (ps) != 0)
  1392.       {
  1393.         hi = (long) Operand1 (ps) % (long) Operand2 (ps);
  1394.         lo = (long) Operand1 (ps) / (long) Operand2 (ps);
  1395.       }
  1396.     else
  1397.       {
  1398.         hi = HI;
  1399.         lo = LO;
  1400.       }
  1401.  
  1402.     HI_present = 0;
  1403.     LO_present = 0;
  1404.     pMDU->hi_val = hi;
  1405.     pMDU->lo_val = lo;
  1406.     /* -1 is for this cycle */
  1407.     pMDU->count = DIV_COST - 1;
  1408.  
  1409.     set_ex_bypass(0, 0);
  1410.     break;
  1411.       }
  1412.  
  1413.     case Y_DIVU_OP:
  1414.       {reg_word hi, lo;
  1415.  
  1416.        if (Operand2 (ps) != 0)
  1417.      {
  1418.        hi = (unsigned long) Operand1 (ps) % (unsigned long) Operand2 (ps);
  1419.        lo = (unsigned long) Operand1 (ps) / (unsigned long) Operand2 (ps);
  1420.      }
  1421.        else
  1422.      {
  1423.        hi = HI;
  1424.        lo = LO;
  1425.      }
  1426.  
  1427.        HI_present = 0;
  1428.        LO_present = 0;
  1429.        pMDU->hi_val = hi;
  1430.        pMDU->lo_val = lo;
  1431.        /* -1 is for this cycle */
  1432.        pMDU->count = DIV_COST - 1;
  1433.        set_ex_bypass(0, 0);
  1434.        break;
  1435.      }
  1436.  
  1437.     case Y_J_OP:
  1438.       set_ex_bypass(0, 0);
  1439.       break;
  1440.  
  1441.     case Y_JAL_OP:
  1442.       VALUE (ps) = STAGE_PC(ps) + 2 * BYTES_PER_WORD;
  1443.       set_ex_bypass(31, VALUE (ps));
  1444.       break;
  1445.  
  1446.     case Y_JALR_OP:
  1447.       VALUE (ps) =  STAGE_PC(ps) + 2 * BYTES_PER_WORD;
  1448.       set_ex_bypass(RD (inst), VALUE (ps));
  1449.       break;
  1450.  
  1451.     case Y_JR_OP:
  1452.       set_ex_bypass(0, 0);
  1453.       break;
  1454.  
  1455.     case Y_LB_OP:
  1456.     case Y_LBU_OP:
  1457.     case Y_LH_OP:
  1458.     case Y_LHU_OP:
  1459.     case Y_LW_OP:
  1460.     case Y_LWC0_OP:
  1461.     case Y_LWC2_OP:
  1462.     case Y_LWC3_OP:
  1463.     case Y_LWL_OP:
  1464.     case Y_LWR_OP:
  1465.       ADDR (ps) = read_R_reg(BASE (inst)) + IOFFSET (inst);
  1466.       set_ex_bypass(0, 0);
  1467.       break;
  1468.  
  1469.     case Y_LWC1_OP:
  1470.       clr_single_present(FT (inst));
  1471.       ADDR (ps) = read_R_reg(BASE (inst)) + IOFFSET (inst);
  1472.       set_ex_bypass(0, 0);
  1473.       break;
  1474.  
  1475.     case Y_LUI_OP:
  1476.       VALUE (ps) = (Operand2 (ps) << 16) & 0xffff0000;
  1477.       set_ex_bypass(RT (inst), VALUE (ps));
  1478.       break;
  1479.  
  1480.     case Y_MFC0_OP:
  1481.     case Y_MFC2_OP:
  1482.     case Y_MFC3_OP:
  1483.       VALUE (ps) = Operand1 (ps);
  1484.       set_ex_bypass(0, 0);
  1485.       break;
  1486.  
  1487.     case Y_MFC1_OP:
  1488.       /* DO nothing...value is read in MEM */
  1489.       set_ex_bypass(0, 0);
  1490.       break;
  1491.  
  1492.     case Y_MFHI_OP:
  1493.       VALUE (ps) = Operand1 (ps);
  1494.       set_ex_bypass(RD (inst), VALUE (ps));
  1495.       break;
  1496.  
  1497.     case Y_MFLO_OP:
  1498.       VALUE (ps) = Operand1 (ps);
  1499.       set_ex_bypass(RD (inst), VALUE (ps));
  1500.       break;
  1501.  
  1502.     case Y_MTC0_OP:
  1503.     case Y_MTC2_OP:
  1504.     case Y_MTC3_OP:
  1505.       VALUE (ps) = Operand2 (ps);
  1506.       set_ex_bypass(0, 0);
  1507.       break;
  1508.  
  1509.     case Y_MTC1_OP:
  1510.       VALUE (ps) = Operand2 (ps);
  1511.       set_ex_bypass(0, 0);
  1512.       break;
  1513.  
  1514.     case Y_MTHI_OP:
  1515.       HI = Operand1 (ps);
  1516.       set_ex_bypass(0, 0);
  1517.       break;
  1518.  
  1519.     case Y_MTLO_OP:
  1520.       LO = Operand1 (ps);
  1521.       set_ex_bypass(0, 0);
  1522.       break;
  1523.  
  1524.     case Y_MULT_OP:
  1525.       {
  1526.     reg_word v1 = Operand1 (ps), v2 = Operand2 (ps);
  1527.     reg_word lo, hi;
  1528.     int neg_sign = 0;
  1529.  
  1530.     if (v1 < 0)
  1531.       v1 = - v1, neg_sign = 1;
  1532.     if (v2 < 0)
  1533.       v2 = - v2, neg_sign = ! neg_sign;
  1534.  
  1535.  
  1536.     long_multiply (v1, v2, &hi, &lo);
  1537.     if (neg_sign)
  1538.       {
  1539.         int carry = 0;
  1540.  
  1541.         lo = ~ lo;
  1542.         hi = ~ hi;
  1543.         carry = lo & 0x80000000;
  1544.         lo += 1;
  1545.         if ((lo ^ carry) == 1)
  1546.           hi += 1;
  1547.       }
  1548.  
  1549.     HI_present = 0;
  1550.     LO_present = 0;
  1551.     pMDU->hi_val = hi;
  1552.     pMDU->lo_val = lo;
  1553.     /* -1 is for this cycle */
  1554.     pMDU->count = MULT_COST - 1;
  1555.  
  1556.     set_ex_bypass(0, 0);
  1557.     break;
  1558.       }
  1559.  
  1560.     case Y_MULTU_OP:
  1561.       {reg_word hi, lo;
  1562.  
  1563.        long_multiply (Operand1 (ps), Operand2 (ps), &hi, &lo);
  1564.  
  1565.        HI_present = 0;
  1566.        LO_present = 0;
  1567.        pMDU->hi_val = hi;
  1568.        pMDU->lo_val = lo;
  1569.        /* -1 is for this cycle */
  1570.        pMDU->count = MULT_COST - 1;
  1571.  
  1572.        set_ex_bypass(0, 0);
  1573.        break;
  1574.      }
  1575.  
  1576.     case Y_NOR_OP:
  1577.       VALUE (ps) = ~ (Operand1 (ps) | Operand2 (ps));
  1578.       set_ex_bypass(RD (inst), VALUE (ps));
  1579.       break;
  1580.  
  1581.  
  1582.     case Y_OR_OP:
  1583.       VALUE (ps) = Operand1 (ps) | Operand2 (ps);
  1584.       set_ex_bypass(RD (inst), VALUE (ps));
  1585.       break;
  1586.  
  1587.     case Y_ORI_OP:
  1588.       /* why is the 0xffff necessary */
  1589.       VALUE (ps) = Operand1 (ps) | (0xffff & Operand2 (ps));
  1590.       set_ex_bypass(RT (inst), VALUE (ps));
  1591.       break;
  1592.  
  1593.     case Y_RFE_OP:
  1594.       /* but without kernel code, this should never occur */
  1595.       Status_Reg = (Status_Reg & 0xfffffff0) | ((Status_Reg & 0x3c) >> 2);
  1596.       set_ex_bypass(0, 0);
  1597.       break;
  1598.  
  1599.     case Y_SB_OP:
  1600.     case Y_SH_OP:
  1601.       ADDR (ps) = Operand2 (ps) + Operand3 (ps);
  1602.       VALUE (ps) = Operand1 (ps);
  1603.       set_ex_bypass(0, 0);
  1604.       break;
  1605.  
  1606.     case Y_SLL_OP:
  1607.       {
  1608.     int shamt = SHAMT (inst);
  1609.  
  1610.     if (shamt >= 0 && shamt < 32)
  1611.       VALUE (ps) = Operand2 (ps) << shamt;
  1612.     else
  1613.       VALUE (ps) = Operand2 (ps);
  1614.  
  1615.     set_ex_bypass(RD (inst), VALUE (ps));
  1616.     break;
  1617.       }
  1618.  
  1619.     case Y_SLLV_OP:
  1620.       {
  1621.     int shamt = (Operand1 (ps) & 0x1f);
  1622.  
  1623.     if (shamt >= 0 && shamt < 32)
  1624.       VALUE (ps) = Operand2 (ps) << shamt;
  1625.     else
  1626.       VALUE (ps) = Operand2 (ps);
  1627.  
  1628.     set_ex_bypass(RD (inst), VALUE (ps));
  1629.     break;
  1630.       }
  1631.  
  1632.     case Y_SLT_OP:
  1633.       if (Operand1 (ps) < Operand2 (ps))
  1634.     VALUE (ps) = 1;
  1635.       else
  1636.     VALUE (ps) = 0;
  1637.  
  1638.       set_ex_bypass(RD (inst), VALUE (ps));
  1639.       break;
  1640.  
  1641.     case Y_SLTI_OP:
  1642.       if (Operand1 (ps) < (short) Operand2 (ps))
  1643.     VALUE (ps) = 1;
  1644.       else
  1645.     VALUE (ps) = 0;
  1646.  
  1647.       set_ex_bypass(RT (inst), VALUE (ps));
  1648.       break;
  1649.  
  1650.     case Y_SLTIU_OP:
  1651.       {
  1652.     int x = (short) Operand2 (ps);
  1653.  
  1654.     if ((unsigned long) Operand1 (ps) < (unsigned long) x)
  1655.       VALUE (ps) = 1;
  1656.     else
  1657.       VALUE (ps) = 0;
  1658.  
  1659.     set_ex_bypass(RT (inst), VALUE (ps));
  1660.     break;
  1661.       }
  1662.  
  1663.     case Y_SLTU_OP:
  1664.       if ((unsigned long) Operand1 (ps) < (unsigned long) Operand2 (ps))
  1665.     VALUE (ps) = 1;
  1666.       else
  1667.     VALUE (ps) = 0;
  1668.  
  1669.       set_ex_bypass(RD (inst), VALUE (ps));
  1670.       break;
  1671.  
  1672.     case Y_SRA_OP:
  1673.       {
  1674.     int shamt = SHAMT (inst);
  1675.     long val = Operand2 (ps);
  1676.  
  1677.     if (shamt >= 0 && shamt < 32)
  1678.       VALUE (ps) = val >> shamt;
  1679.     else
  1680.       VALUE (ps) = val;
  1681.  
  1682.     set_ex_bypass(RD (inst), VALUE (ps));
  1683.     break;
  1684.       }
  1685.  
  1686.     case Y_SRAV_OP:
  1687.       {
  1688.     int shamt = Operand1 (ps) & 0x1f;
  1689.     long val = Operand2 (ps);
  1690.  
  1691.     if (shamt >= 0 && shamt < 32)
  1692.       VALUE (ps) = val >> shamt;
  1693.     else
  1694.       VALUE (ps) = val;
  1695.  
  1696.     set_ex_bypass(RD (inst), VALUE (ps));
  1697.     break;
  1698.       }
  1699.  
  1700.     case Y_SRL_OP:
  1701.       {
  1702.     int shamt = SHAMT (inst);
  1703.     unsigned long val = Operand2 (ps);
  1704.  
  1705.     if (shamt >= 0 && shamt < 32)
  1706.       VALUE (ps) = val >> shamt;
  1707.     else
  1708.       VALUE (ps) = val;
  1709.  
  1710.     set_ex_bypass(RD (inst), VALUE (ps));
  1711.     break;
  1712.       }
  1713.  
  1714.     case Y_SRLV_OP:
  1715.       {
  1716.     int shamt = Operand1 (ps) & 0x1f;
  1717.     unsigned long val = Operand2 (ps);
  1718.  
  1719.     if (shamt >= 0 && shamt < 32)
  1720.       VALUE (ps) = val >> shamt;
  1721.     else
  1722.       VALUE (ps) = val;
  1723.  
  1724.     set_ex_bypass(RD (inst), VALUE (ps));
  1725.     break;
  1726.       }
  1727.  
  1728.     case Y_SUB_OP:
  1729.       {
  1730.     register reg_word vs = Operand1 (ps), vt = Operand2 (ps);
  1731.     register reg_word diff = vs - vt;
  1732.  
  1733.     if (SIGN_BIT (vs) != SIGN_BIT (vt)
  1734.         && SIGN_BIT (vs) != SIGN_BIT (diff))
  1735.       CL_RAISE_EXCEPTION (OVF_EXCPT, 0, EXCPT(ps));
  1736.  
  1737.     VALUE (ps) = diff;
  1738.  
  1739.     set_ex_bypass(RD (inst), diff);
  1740.     break;
  1741.       }
  1742.  
  1743.     case Y_SUBU_OP:
  1744.       VALUE (ps) = (unsigned long) Operand1 (ps) - (unsigned long) Operand2 (ps);
  1745.  
  1746.       set_ex_bypass(RD (inst), VALUE (ps));
  1747.       break;
  1748.  
  1749.     case Y_SW_OP:
  1750.     case Y_SWC0_OP:
  1751.     case Y_SWC1_OP:
  1752.     case Y_SWC3_OP:
  1753.     case Y_SWL_OP:
  1754.     case Y_SWR_OP:
  1755.       ADDR (ps) = Operand2 (ps) + Operand3 (ps);
  1756.       VALUE (ps) = Operand1 (ps);
  1757.       set_ex_bypass(0, 0);
  1758.       break;
  1759.  
  1760.     case Y_SWC2_OP:
  1761.       /* do nothing, SWC2 is being used to print memory stats */
  1762.       break;
  1763.  
  1764.     case Y_SYSCALL_OP:
  1765.       break;
  1766.  
  1767.     case Y_TLBP_OP:
  1768.     case Y_TLBR_OP:
  1769.     case Y_TLBWI_OP:
  1770.     case Y_TLBWR_OP:
  1771.       /* what to do? */
  1772.       break;
  1773.  
  1774.     case Y_XOR_OP:
  1775.       VALUE (ps) = Operand1 (ps) ^ Operand2 (ps);
  1776.       set_ex_bypass(RD (inst), VALUE (ps));
  1777.       break;
  1778.  
  1779.     case Y_XORI_OP:
  1780.       /* why is the 0xffff necessary */
  1781.       VALUE (ps) = Operand1 (ps) ^ (0xffff & Operand2 (ps));
  1782.       set_ex_bypass(RT (inst), VALUE (ps));
  1783.       break;
  1784.  
  1785.  
  1786.     default:
  1787.       /* What to do? */
  1788.       break;
  1789.     }
  1790.  
  1791. }
  1792.  
  1793.  
  1794.  
  1795. /* process memory stage */
  1796. /* need to handle misses and faults */
  1797.  
  1798. #ifdef __STDC__
  1799. static int
  1800. process_MEM (PIPE_STAGE ps, MEM_SYSTEM mem_sys)
  1801. #else
  1802. static int
  1803. process_MEM (ps, mem_sys)
  1804.      PIPE_STAGE ps;
  1805.      MEM_SYSTEM mem_sys;
  1806. #endif
  1807. {
  1808.   instruction *inst;
  1809.   int cmiss = -1;
  1810.  
  1811.   inst = ps->inst;
  1812.  
  1813.   /* only load instructions update the MEM bypass variables
  1814.      to something other than the values generated by the EX stage */
  1815.   set_mem_bypass(EX_bp_reg, EX_bp_val);
  1816.   /* Kill old CP bypass values */
  1817.   set_CP_bypass(-1, -1 , -1, -1);
  1818.  
  1819.   switch (OPCODE (inst))
  1820.     {
  1821.     case Y_LB_OP:
  1822.       CL_READ_MEM_BYTE(mem_sys, VALUE(ps), ADDR (ps), PADDR (ps), cmiss, EXCPT (ps), RNUM (ps));
  1823.       if (EXCPT (ps) == 0)
  1824.     set_mem_bypass(RT (inst), VALUE (ps));
  1825.       break;
  1826.  
  1827.     case Y_LBU_OP:
  1828.       CL_READ_MEM_BYTE(mem_sys, VALUE(ps), ADDR (ps), PADDR (ps), cmiss, EXCPT (ps), RNUM (ps));
  1829.       if (EXCPT (ps) == 0) {
  1830.     /* 0xff is probably not necessary */
  1831.     VALUE (ps) &= 0xff;
  1832.     set_mem_bypass(RT (inst), VALUE (ps));
  1833.       }
  1834.       break;
  1835.  
  1836.     case Y_LH_OP:
  1837.       CL_READ_MEM_HALF(mem_sys, VALUE(ps), ADDR (ps), PADDR (ps), cmiss, EXCPT (ps), RNUM (ps));
  1838.       if (EXCPT (ps) == 0)
  1839.     set_mem_bypass(RT (inst), VALUE (ps));
  1840.       break;
  1841.  
  1842.     case Y_LHU_OP:
  1843.       CL_READ_MEM_HALF(mem_sys, VALUE(ps), ADDR (ps), PADDR (ps), cmiss, EXCPT (ps), RNUM (ps));
  1844.       if (EXCPT (ps) == 0) {
  1845.     /* 0xffff is probably not necessary */
  1846.     VALUE (ps) &= 0xffff;
  1847.     set_mem_bypass(RT (inst), VALUE (ps));
  1848.       }
  1849.       break;
  1850.  
  1851.     case Y_LW_OP:
  1852.       CL_READ_MEM_WORD(mem_sys, VALUE(ps), ADDR (ps), PADDR (ps), cmiss, EXCPT (ps), RNUM (ps));
  1853.       if (EXCPT (ps) == 0)
  1854.     set_mem_bypass(RT (inst), VALUE (ps));
  1855.       break;
  1856.  
  1857.     case Y_LWC0_OP:
  1858.     case Y_LWC2_OP:
  1859.     case Y_LWC3_OP:
  1860.       CL_READ_MEM_WORD(mem_sys, VALUE(ps), ADDR (ps), PADDR (ps), cmiss, EXCPT (ps), RNUM (ps));
  1861.       if (EXCPT (ps) == 0)
  1862.     set_CP_bypass((OPCODE (inst) - Y_LWC0_OP), RT (inst), VALUE (ps), 1)
  1863.       else
  1864.     /* Exception occurred.  Need to reset the register
  1865.      * presence bits, so that after the fault, the instruction
  1866.      * can restart */
  1867.     set_single_present(FT (inst));
  1868.       break;
  1869.  
  1870.  
  1871.     case Y_LWC1_OP:
  1872.       CL_READ_MEM_WORD(mem_sys, VALUE(ps), ADDR (ps), PADDR (ps), cmiss, EXCPT (ps), RNUM (ps));
  1873.       if (EXCPT (ps) == 0)
  1874.     set_CP_bypass((OPCODE (inst) - Y_LWC0_OP), RT (inst), VALUE (ps), 1)
  1875.       else
  1876.     /* Exception occurred.  Need to reset the register
  1877.      * presence bits, so that after the fault, the instruction
  1878.      * can restart */
  1879.     set_single_present(FT (inst));
  1880.       break;
  1881.  
  1882.     case Y_LWL_OP:
  1883.       {
  1884.     register mem_addr addr = ADDR (ps);
  1885.     reg_word word;    /* Can't be register */
  1886.     register int byte = addr & 0x3;
  1887.     /* is this right? -- NO need bypass value from memory stage of previous
  1888.        instruction. */
  1889.     reg_word reg_val = R[RT (inst)];
  1890.  
  1891.     CL_READ_MEM_WORD(mem_sys, word, addr & 0xfffffffc, PADDR (ps), cmiss,
  1892.              EXCPT (ps), RNUM (ps));
  1893.     /* Fix this */
  1894. /*    if ((Cause >> 2) > LAST_REAL_EXCEPT) */
  1895.     if (Cause == 0)
  1896. #ifdef BIGENDIAN
  1897.       switch (byte)
  1898.         {
  1899.         case 0:
  1900.           VALUE (ps) = word;
  1901.           break;
  1902.  
  1903.         case 1:
  1904.           VALUE (ps) = (word & 0xffffff) << 8 | (reg_val & 0xff);
  1905.           break;
  1906.  
  1907.         case 2:
  1908.           VALUE (ps) = (word & 0xffff) << 16 | (reg_val & 0xffff);
  1909.           break;
  1910.  
  1911.         case 3:
  1912.           VALUE (ps) = (word & 0xff) << 24 | (reg_val & 0xffffff);
  1913.           break;
  1914.           }
  1915. #else
  1916.     switch (byte)
  1917.       {
  1918.       case 0:
  1919.         VALUE (ps) = (word & 0xff) << 24 | (reg_val & 0xffffff);
  1920.         break;
  1921.  
  1922.       case 1:
  1923.         VALUE (ps) = (word & 0xffff) << 16 | (reg_val & 0xffff);
  1924.         break;
  1925.  
  1926.       case 2:
  1927.         VALUE (ps) = (word & 0xffffff) << 8 | (reg_val & 0xff);
  1928.         break;
  1929.  
  1930.       case 3:
  1931.         VALUE (ps) = word;
  1932.         break;
  1933.       }
  1934. #endif
  1935.     set_mem_bypass(RT (inst), VALUE (ps));
  1936.  
  1937.     break;
  1938.       }
  1939.  
  1940.     case Y_LWR_OP:
  1941.       {
  1942.     register mem_addr addr = ADDR (ps);
  1943.     reg_word word;    /* Can't be register */
  1944.     register int byte = addr & 0x3;
  1945.     /* is this right? */
  1946.     reg_word reg_val = R[RT (inst)];
  1947.  
  1948.         CL_READ_MEM_WORD(mem_sys, word, addr & 0xfffffffc, PADDR (ps), cmiss,
  1949.              EXCPT (ps), RNUM (ps));
  1950.     /* fix this */
  1951.  
  1952. /*    if ((Cause >> 2) > LAST_REAL_EXCEPT) */
  1953.     if (Cause == 0)
  1954. #ifdef BIGENDIAN
  1955.       switch (byte)
  1956.         {
  1957.         case 0:
  1958.           VALUE (ps) = (reg_val & 0xffffff00)
  1959.         | ((word & 0xff000000) >> 24);
  1960.           break;
  1961.  
  1962.         case 1:
  1963.           VALUE (ps) = (reg_val & 0xffff0000)
  1964.         | ((word & 0xffff0000) >> 16);
  1965.           break;
  1966.  
  1967.         case 2:
  1968.           VALUE (ps) = (reg_val & 0xff000000)
  1969.         | ((word & 0xffffff00) >> 8);
  1970.           break;
  1971.  
  1972.         case 3:
  1973.           VALUE (ps) = word;
  1974.           break;
  1975.         }
  1976. #else
  1977.     switch (byte)
  1978.       {
  1979.         /* NB: The description of the little-endian case in Kane is
  1980.            totally wrong. */
  1981.       case 0:        /* 3 in book */
  1982.         VALUE (ps) = reg_val;
  1983.         break;
  1984.  
  1985.       case 1:        /* 0 in book */
  1986.         VALUE (ps) = (reg_val & 0xff000000)
  1987.           | ((word & 0xffffff00) >> 8);
  1988.         break;
  1989.  
  1990.       case 2:        /* 1 in book */
  1991.         VALUE (ps) = (reg_val & 0xffff0000)
  1992.           | ((word & 0xffff0000) >> 16);
  1993.         break;
  1994.  
  1995.       case 3:        /* 2 in book */
  1996.         VALUE (ps) = (reg_val & 0xffffff00)
  1997.           | ((word & 0xff000000) >> 24);
  1998.         break;
  1999.       }
  2000. #endif
  2001.     set_mem_bypass(RT (inst), VALUE (ps));
  2002.     break;
  2003.       }
  2004.  
  2005.  
  2006.     case Y_SB_OP:
  2007.       CL_SET_MEM_BYTE(mem_sys, ADDR (ps), PADDR (ps), VALUE (ps), cmiss, EXCPT(ps),
  2008.               RNUM (ps));
  2009.       break;
  2010.  
  2011.     case Y_SH_OP:
  2012.       CL_SET_MEM_HALF(mem_sys, ADDR (ps), PADDR (ps), VALUE (ps), cmiss, EXCPT(ps),
  2013.               RNUM (ps));
  2014.       break;
  2015.  
  2016.     case Y_SW_OP:
  2017.       CL_SET_MEM_WORD(mem_sys, ADDR (ps), PADDR (ps), VALUE (ps), cmiss, EXCPT(ps),
  2018.               RNUM (ps));
  2019.       break;
  2020.  
  2021.     case Y_SWC1_OP:
  2022.       {
  2023.     float val = FGR [RT (inst)];
  2024.     reg_word *vp = (reg_word *) &val;
  2025.  
  2026.     CL_SET_MEM_WORD (mem_sys, ADDR (ps), PADDR (ps), *vp, cmiss, EXCPT (ps),
  2027.              RNUM (ps));
  2028.     break;
  2029.       }
  2030.  
  2031.     case Y_SWC0_OP:
  2032.     case Y_SWC3_OP:
  2033.       CL_SET_MEM_WORD(mem_sys, ADDR (ps), PADDR (ps), VALUE (ps), cmiss, EXCPT(ps),
  2034.               RNUM (ps));
  2035.       break;
  2036.  
  2037.  
  2038.     case Y_SWC2_OP:
  2039.       /* do nothing, SWC2 is being used to print memory stats */
  2040.       break;
  2041.  
  2042.     case Y_SWL_OP:
  2043.       {
  2044.     register mem_addr addr = ADDR (ps);
  2045.     mem_word data;
  2046.     reg_word reg = R[RT (inst)];
  2047.     register int byte = addr & 0x3;
  2048.  
  2049.     CL_READ_MEM_WORD (mem_sys, data, addr & 0xfffffffc, PADDR (ps), cmiss,
  2050.               EXCPT (ps), RNUM (ps));
  2051.  
  2052. #ifdef BIGENDIAN
  2053.     switch (byte)
  2054.       {
  2055.       case 0:
  2056.         data = reg;
  2057.         break;
  2058.  
  2059.       case 1:
  2060.         data = (data & 0xff000000) | (reg >> 8 & 0xffffff);
  2061.         break;
  2062.  
  2063.       case 2:
  2064.         data = (data & 0xffff0000) | (reg >> 16 & 0xffff);
  2065.         break;
  2066.  
  2067.       case 3:
  2068.         data = (data & 0xffffff00) | (reg >> 24 & 0xff);
  2069.         break;
  2070.       }
  2071. #else
  2072.     switch (byte)
  2073.       {
  2074.       case 0:
  2075.         data = (data & 0xffffff00) | (reg >> 24 & 0xff);
  2076.         break;
  2077.  
  2078.       case 1:
  2079.         data = (data & 0xffff0000) | (reg >> 16 & 0xffff);
  2080.         break;
  2081.  
  2082.       case 2:
  2083.         data = (data & 0xff000000) | (reg >> 8 & 0xffffff);
  2084.         break;
  2085.  
  2086.       case 3:
  2087.         data = reg;
  2088.         break;
  2089.       }
  2090. #endif
  2091.     CL_SET_MEM_WORD (mem_sys, addr & 0xfffffffc, PADDR (ps), data, cmiss,
  2092.              EXCPT(ps), RNUM (ps));
  2093.     break;
  2094.       }
  2095.  
  2096.     case Y_SWR_OP:
  2097.       {
  2098.     register mem_addr addr = R[BASE (inst)] + IOFFSET (inst);
  2099.     mem_word data;
  2100.     reg_word reg = R[RT (inst)];
  2101.     register int byte = addr & 0x3;
  2102.  
  2103.     CL_READ_MEM_WORD (mem_sys, data, addr & 0xfffffffc, PADDR (ps), cmiss,
  2104.               EXCPT (ps), RNUM (ps));
  2105.  
  2106. #ifdef BIGENDIAN
  2107.     switch (byte)
  2108.       {
  2109.       case 0:
  2110.         data = ((reg << 24) & 0xff000000) | (data & 0xffffff);
  2111.         break;
  2112.  
  2113.       case 1:
  2114.         data = ((reg << 16) & 0xffff0000) | (data & 0xffff);
  2115.         break;
  2116.  
  2117.       case 2:
  2118.         data = ((reg << 8) & 0xffffff00) | (data & 0xff) ;
  2119.         break;
  2120.  
  2121.       case 3:
  2122.         data = reg;
  2123.         break;
  2124.       }
  2125. #else
  2126.     switch (byte)
  2127.       {
  2128.       case 0:
  2129.         data = reg;
  2130.         break;
  2131.  
  2132.       case 1:
  2133.         data = ((reg << 8) & 0xffffff00) | (data & 0xff) ;
  2134.         break;
  2135.  
  2136.       case 2:
  2137.         data = ((reg << 16) & 0xffff0000) | (data & 0xffff);
  2138.         break;
  2139.  
  2140.       case 3:
  2141.         data = ((reg << 24) & 0xff000000) | (data & 0xffffff);
  2142.         break;
  2143.       }
  2144. #endif
  2145.     CL_SET_MEM_WORD (mem_sys, addr & 0xfffffffc, PADDR (ps), data, cmiss,
  2146.              EXCPT(ps), RNUM (ps));
  2147.     break;
  2148.       }
  2149.  
  2150.     case Y_SYSCALL_OP:
  2151.       break;
  2152.  
  2153.     case Y_TLBP_OP:
  2154.       tlbp();
  2155.       break;
  2156.  
  2157.     case Y_TLBR_OP:
  2158.       tlbr();
  2159.       break;
  2160.  
  2161.     case Y_TLBWI_OP:
  2162.       tlbwi();
  2163.       break;
  2164.  
  2165.     case Y_TLBWR_OP:
  2166.       tlbwr();
  2167.       break;
  2168.  
  2169.     case Y_CFC0_OP:
  2170.     case Y_CFC2_OP:
  2171.     case Y_CFC3_OP:
  2172.     case Y_MFC0_OP:
  2173.     case Y_MFC2_OP:
  2174.     case Y_MFC3_OP:
  2175.       set_mem_bypass(RT (inst), VALUE (ps));
  2176.       break;
  2177.  
  2178.     case Y_MFC1_OP:
  2179.       {  /* Read value from register file to avoid extra
  2180.      conversion to double precision */
  2181.     float val = FGR [RD (inst)]; /* RD not FS */
  2182.     reg_word *vp = (reg_word *) &val;
  2183.  
  2184.     set_mem_bypass(RT (inst), *vp);
  2185.     break;
  2186.       }
  2187.  
  2188.     case Y_CTC0_OP:
  2189.     case Y_CTC2_OP:
  2190.     case Y_CTC3_OP:
  2191.       set_CP_bypass((OPCODE (inst) - Y_CTC0_OP), RD (inst), VALUE (ps), 0);
  2192.       break;
  2193.  
  2194.     case Y_MTC0_OP:
  2195.     case Y_MTC2_OP:
  2196.     case Y_MTC3_OP:
  2197.       set_CP_bypass((OPCODE (inst) - Y_MTC0_OP), RD (inst), VALUE (ps), 1);
  2198.       break;
  2199.  
  2200.     default:
  2201.       /* nothing to do for the following op codes
  2202.     case Y_ADD_OP:    case Y_ADDI_OP:          case Y_ADDIU_OP:     case Y_ADDU_OP:
  2203.     case Y_AND_OP:     case Y_ANDI_OP:    case Y_BC0F_OP:      case Y_BC2F_OP:
  2204.     case Y_BC3F_OP:    case Y_BC0T_OP:    case Y_BC2T_OP:      case Y_BC3T_OP:
  2205.     case Y_BEQ_OP:     case Y_BGEZ_OP:    case Y_BGEZAL_OP:    case Y_BGTZ_OP:
  2206.     case Y_BLEZ_OP:    case Y_BLTZ_OP:    case Y_BLTZAL_OP:    case Y_BNE_OP:
  2207.     case Y_BREAK_OP:   case Y_COP0_OP:    case Y_COP1_OP:      case Y_COP2_OP:
  2208.     case Y_COP3_OP:    case Y_DIV_OP:     case Y_DIVU_OP:      case Y_J_OP:
  2209.     case Y_JAL_OP:     case Y_JALR_OP:    case Y_JR_OP:        case Y_LUI_OP
  2210.     case Y_MFHI_OP:    case Y_MFLO_OP:    case Y_MTHI_OP:      case Y_MTLO_OP:
  2211.     case Y_MULT_OP:       case Y_MULTU_OP:   case Y_NOR_OP:       case Y_OR_OP:
  2212.     case Y_ORI_OP:       case Y_RFE_OP:     case Y_SLL_OP:       case Y_SLLV_OP:
  2213.     case Y_SLT_OP:       case Y_SLTI_OP:    case Y_SLTIU_OP:       case Y_SLTU_OP:
  2214.     case Y_SRA_OP:       case Y_SRAV_OP:    case Y_SRL_OP:       case Y_SRLV_OP:
  2215.     case Y_SUB_OP:       case Y_SUBU_OP:    case Y_XOR_OP:       case Y_XORI_OP:
  2216.     */
  2217.       break;
  2218.     }
  2219.  
  2220.   return (cmiss);
  2221. }
  2222.  
  2223.  
  2224. /* Simulate WB stage */
  2225. /* when sure it's right combine cases that have the same code. */
  2226.  
  2227. #ifdef __STDC__
  2228. static int
  2229. process_WB (PIPE_STAGE ps)
  2230. #else
  2231. static int
  2232. process_WB (ps)
  2233.      PIPE_STAGE ps;
  2234. #endif
  2235. {
  2236.   register instruction *inst;
  2237.   register int value;
  2238.  
  2239.   inst = ps->inst;
  2240.   value = VALUE (ps);
  2241.  
  2242.   switch (OPCODE (inst))
  2243.     {
  2244.     case Y_ADD_OP:   case Y_ADDU_OP:  case Y_AND_OP:  case Y_JALR_OP:
  2245.     case Y_MFHI_OP:  case Y_MFLO_OP:  case Y_NOR_OP:  case Y_OR_OP:
  2246.     case Y_SRLV_OP:  case Y_SRL_OP:   case Y_SRAV_OP: case Y_SRA_OP:
  2247.     case Y_SLTU_OP:  case Y_SLT_OP:   case Y_SLLV_OP: case Y_SLL_OP:
  2248.     case Y_SUBU_OP:  case Y_SUB_OP:   case Y_XOR_OP:
  2249.       R[RD (inst)] = value;
  2250.       break;
  2251.  
  2252.     case Y_ADDI_OP:  case Y_ADDIU_OP:  case Y_ANDI_OP:  case Y_CFC0_OP:
  2253.     case Y_CFC2_OP:  case Y_CFC3_OP:   case Y_LB_OP:
  2254.     case Y_LBU_OP:   case Y_LH_OP:     case Y_LHU_OP:   case Y_LUI_OP:
  2255.     case Y_LW_OP:    case Y_LWL_OP:    case Y_LWR_OP:   case Y_MFC0_OP:
  2256.     case Y_MFC2_OP:  case Y_MFC3_OP:   case Y_ORI_OP:   case Y_SLTI_OP:
  2257.     case Y_SLTIU_OP: case Y_XORI_OP:
  2258.  
  2259.       R[RT (inst)] = value;
  2260.       break;
  2261.  
  2262.     case Y_MFC1_OP:
  2263.       /* Read value from register file to avoid extra
  2264.      conversion to double precision */
  2265.       { float val = FGR [RD (inst)]; /* RD not FS */
  2266.     reg_word *vp = (reg_word *) &val;
  2267.  
  2268.     R[RT (inst)] = *vp;    /* Fool coercion */
  2269.     break;
  2270.       }
  2271.  
  2272.  
  2273.     case Y_BC0F_OP:  case Y_BC2F_OP:  case Y_BC3F_OP:  case Y_BC0T_OP:
  2274.     case Y_BC1F_OP:  case Y_BC1T_OP:
  2275.     case Y_BC2T_OP:  case Y_BC3T_OP:  case Y_BEQ_OP:   case Y_BGEZ_OP:
  2276.     case Y_BGTZ_OP:  case Y_BLEZ_OP:  case Y_BLTZ_OP:  case Y_BNE_OP:
  2277.     case Y_J_OP:     case Y_JR_OP:    case Y_SB_OP:    case Y_SH_OP:
  2278.     case Y_SW_OP:    case Y_SWC0_OP:  case Y_SWC3_OP:
  2279.     case Y_SWL_OP:   case Y_SWR_OP:   case Y_TLBP_OP:  case Y_TLBR_OP:
  2280.     case Y_TLBWI_OP: case Y_TLBWR_OP: case Y_SWC1_OP:
  2281.       /* no write back */    break;
  2282.  
  2283.     case Y_SWC2_OP:
  2284.       /* do nothing, SWC2 is being used to print memory stats */
  2285.       break;
  2286.  
  2287.     case Y_BGEZAL_OP: case Y_BLTZAL_OP: case Y_JAL_OP:
  2288.       if (!DSLOT (ps))
  2289.     R[31] = value;
  2290.       break;
  2291.  
  2292.     case Y_BREAK_OP:
  2293.       break;
  2294.  
  2295.     case Y_COP0_OP: case Y_COP1_OP:
  2296.     case Y_COP2_OP: case Y_COP3_OP:
  2297.       CCR [OPCODE (inst) - Y_COP0_OP] [RD (inst)] = value;
  2298.       break;
  2299.  
  2300.     case Y_CTC0_OP:
  2301.     case Y_CTC2_OP:
  2302.     case Y_CTC3_OP:
  2303.       CCR [OPCODE (inst) - Y_CTC0_OP] [RD (inst)] = value;
  2304.       break;
  2305.  
  2306.     case Y_DIV_OP:
  2307.     case Y_DIVU_OP:
  2308.     case Y_MTHI_OP:
  2309.     case Y_MTLO_OP:
  2310.     case Y_MULT_OP:
  2311.     case Y_MULTU_OP:
  2312.       /* nothing to do...these values are set in EX/MDU */
  2313.       break;
  2314.  
  2315.  
  2316.     case Y_LWC0_OP:
  2317.     case Y_LWC2_OP:
  2318.     case Y_LWC3_OP:
  2319.       CPR [OPCODE (inst) - Y_LWC0_OP] [RT (inst)] = value;
  2320.       break;
  2321.  
  2322.     case Y_MTC0_OP:
  2323.     case Y_MTC2_OP:
  2324.     case Y_MTC3_OP:
  2325.       CPR [OPCODE (inst) - Y_MTC0_OP] [RD (inst)] = value;
  2326.       break;
  2327.  
  2328.  
  2329.     case Y_RFE_OP:
  2330.       /* Do nothing.  Status_Reg is set in EX */
  2331.       break;
  2332.  
  2333.     case Y_SYSCALL_OP:
  2334.       /* we won't ever get here, syscall causes exception */
  2335.       break;
  2336.  
  2337.     default:
  2338.       /* no EX */
  2339.       break;
  2340.     }
  2341.  
  2342.   return (0);
  2343.   /* Executed enough steps, return, but are able to continue. */
  2344.   /*  return (1);  */
  2345.  
  2346. }
  2347.  
  2348.  
  2349. #ifdef __STDC__
  2350. static int
  2351. process_f_ex1 (PIPE_STAGE ps)
  2352. #else
  2353. static int
  2354. process_f_ex1(ps)
  2355.      PIPE_STAGE ps;
  2356. #endif
  2357. { instruction *inst;
  2358.   int excpt = -1;
  2359.  
  2360.   inst = ps->inst;
  2361.  
  2362.   switch (OPCODE (inst))
  2363.     {
  2364.  
  2365.       /* FPA Operations */
  2366.       /* All counts include a (- 1) to account for this cycle. */
  2367.  
  2368.  
  2369.     case Y_ABS_S_OP:
  2370.     case Y_ABS_D_OP:
  2371.       clr_present(FD (inst));
  2372.       FPvalue (ps) =  fabs (FPoperand1 (ps));
  2373.       Count (ps) = 1 - 1;
  2374.       FP_add_cnt = Count (ps);
  2375.       break;
  2376.  
  2377.     case Y_ADD_S_OP:
  2378.     case Y_ADD_D_OP:
  2379.       clr_present(FD (inst));
  2380.       FPvalue (ps) =  FPoperand1 (ps) + FPoperand2 (ps);
  2381.       Count (ps) = 2 - 1;
  2382.       FP_add_cnt = Count (ps);
  2383.       /* Should trap on inexact/overflow/underflow */
  2384.       break;
  2385.  
  2386.     case Y_C_F_S_OP:
  2387.     case Y_C_UN_S_OP:
  2388.     case Y_C_EQ_S_OP:
  2389.     case Y_C_UEQ_S_OP:
  2390.     case Y_C_OLE_S_OP:
  2391.     case Y_C_ULE_S_OP:
  2392.     case Y_C_SF_S_OP:
  2393.     case Y_C_NGLE_S_OP:
  2394.     case Y_C_SEQ_S_OP:
  2395.     case Y_C_NGL_S_OP:
  2396.     case Y_C_LT_S_OP:
  2397.     case Y_C_NGE_S_OP:
  2398.     case Y_C_LE_S_OP:
  2399.     case Y_C_NGT_S_OP:
  2400.       {
  2401.     float v1 = FPoperand1 (ps), v2 = FPoperand2 (ps);
  2402.     double dv1 = v1, dv2 = v2;
  2403.     int less, equal, unordered;
  2404.     int cond = COND (inst);
  2405.     reg_word tmp_fpcond;
  2406.  
  2407.     if (NaN (dv1) || NaN (dv2))
  2408.       {
  2409.         less = 0;
  2410.         equal = 0;
  2411.         unordered = 1;
  2412.         if (cond & COND_IN)
  2413.           CL_RAISE_EXCEPTION (INVALID_EXCEPT, 0, EXCPT(ps))
  2414.       }
  2415.     else
  2416.       {
  2417.         less = v1 < v2;
  2418.         equal = v1 == v2;
  2419.         unordered = 0;
  2420.       }
  2421.     tmp_fpcond = 0;
  2422.     if (cond & COND_LT)
  2423.       tmp_fpcond |= less;
  2424.     if (cond & COND_EQ)
  2425.       tmp_fpcond |= equal;
  2426.     if (cond & COND_UN)
  2427.       tmp_fpcond |= unordered;
  2428.  
  2429.     VALUE (ps) = tmp_fpcond;
  2430.     Count (ps) = 1-1;
  2431.     FP_add_cnt = Count (ps);
  2432.     break;
  2433.       }
  2434.  
  2435.     case Y_C_F_D_OP:
  2436.     case Y_C_UN_D_OP:
  2437.     case Y_C_EQ_D_OP:
  2438.     case Y_C_UEQ_D_OP:
  2439.     case Y_C_OLE_D_OP:
  2440.     case Y_C_ULE_D_OP:
  2441.     case Y_C_SF_D_OP:
  2442.     case Y_C_NGLE_D_OP:
  2443.     case Y_C_SEQ_D_OP:
  2444.     case Y_C_NGL_D_OP:
  2445.     case Y_C_LT_D_OP:
  2446.     case Y_C_NGE_D_OP:
  2447.     case Y_C_LE_D_OP:
  2448.     case Y_C_NGT_D_OP:
  2449.       {
  2450.     double v1 = FPoperand1 (ps), v2 = FPoperand2 (ps);
  2451.     int less, equal, unordered;
  2452.     int cond = COND (inst);
  2453.     reg_word tmp_fpcond;
  2454.  
  2455.     if (NaN (v1) || NaN (v2))
  2456.       {
  2457.         less = 0;
  2458.         equal = 0;
  2459.         unordered = 1;
  2460.         if (cond & COND_IN)
  2461.           CL_RAISE_EXCEPTION (INVALID_EXCEPT, 0, EXCPT(ps))
  2462.       }
  2463.     else
  2464.       {
  2465.         less = v1 < v2;
  2466.         equal = v1 == v2;
  2467.         unordered = 0;
  2468.       }
  2469.     tmp_fpcond = 0;
  2470.     if (cond & COND_LT)
  2471.       tmp_fpcond |= less;
  2472.     if (cond & COND_EQ)
  2473.       tmp_fpcond |= equal;
  2474.     if (cond & COND_UN)
  2475.       tmp_fpcond |= unordered;
  2476.  
  2477.     VALUE (ps) = tmp_fpcond;
  2478.     Count (ps) = 1-1;
  2479.     FP_add_cnt = Count (ps);
  2480.     break;
  2481.       }
  2482.  
  2483.     case Y_CFC1_OP:
  2484.       /* What to do? */
  2485.       break;
  2486.  
  2487.     case Y_CTC1_OP:
  2488.       /* What to do? */
  2489.       break;
  2490.  
  2491.     case Y_CVT_D_S_OP:
  2492.     case Y_CVT_D_W_OP:
  2493.       clr_present(FD (inst));
  2494.       FPvalue (ps) =  (double) FPoperand1 (ps);
  2495.       Count (ps) = ((OPCODE (inst) == Y_CVT_D_S_OP) ? 1 : 3) - 1;
  2496.       FP_add_cnt = Count (ps);
  2497.       break;
  2498.  
  2499.  
  2500.     case Y_CVT_S_D_OP:
  2501.     case Y_CVT_S_W_OP:
  2502.       clr_present(FD (inst));
  2503.       FPvalue (ps) =  (float) FPoperand1 (ps);
  2504.       Count (ps) =  ((OPCODE (inst) == Y_CVT_S_D_OP) ? 2 : 3) - 1;
  2505.       FP_add_cnt = Count (ps);
  2506.       break;
  2507.  
  2508.  
  2509.     case Y_CVT_W_D_OP:
  2510.     case Y_CVT_W_S_OP:
  2511.       clr_present(FD (inst));
  2512.       FPvalue (ps) =  (float) FPoperand1 (ps);
  2513.       Count (ps) = 2 - 1;
  2514.       FP_add_cnt = Count (ps);
  2515.       break;
  2516.  
  2517.     case Y_DIV_S_OP:
  2518.     case Y_DIV_D_OP:
  2519.       clr_present(FD (inst));
  2520.       FPvalue (ps) =  FPoperand1 (ps) / FPoperand2 (ps);
  2521.       Count (ps) = ((OPCODE (inst) == Y_DIV_S_OP) ? 12 : 19) - 1;
  2522.       FP_div_cnt = Count (ps);
  2523.       break;
  2524.  
  2525.     case Y_LWC1_OP:
  2526.       break;
  2527.  
  2528.  
  2529.     case Y_MOV_S_OP:
  2530.     case Y_MOV_D_OP:
  2531.       clr_present(FD (inst));
  2532.       FPvalue (ps) = FPoperand1 (ps);
  2533.       Count (ps) = 1 - 1;
  2534.       FP_add_cnt = Count (ps);
  2535.       break;
  2536.  
  2537.     case Y_MUL_S_OP:
  2538.     case Y_MUL_D_OP:
  2539.       clr_present(FD (inst));
  2540.       FPvalue (ps) = FPoperand1 (ps) * FPoperand2 (ps);
  2541.       Count (ps) =  ((OPCODE (inst) == Y_MUL_S_OP) ? 4 : 5) - 1;
  2542.       FP_mul_cnt = Count (ps);
  2543.       break;
  2544.  
  2545.  
  2546.     case Y_NEG_S_OP:
  2547.     case Y_NEG_D_OP:
  2548.       clr_present(FD (inst));
  2549.       FPvalue (ps) =  - FPoperand1 (ps);
  2550.       Count (ps) = 1 - 1;
  2551.       FP_add_cnt = Count (ps);
  2552.       break;
  2553.  
  2554.     case Y_SUB_S_OP:
  2555.     case Y_SUB_D_OP:
  2556.       clr_present(FD (inst));
  2557.       FPvalue (ps) =  FPoperand1 (ps) - FPoperand2 (ps);
  2558.       Count (ps) =  2 - 1;
  2559.       FP_add_cnt = Count (ps);
  2560.       break;
  2561.  
  2562.     default:
  2563.       break;
  2564.     }
  2565.  
  2566.   return (excpt);
  2567. }
  2568.  
  2569.  
  2570.  
  2571. #ifdef __STDC__
  2572. static int
  2573. process_f_ex2 (PIPE_STAGE ps)
  2574. #else
  2575. static int
  2576. process_f_ex2 (ps)
  2577.   PIPE_STAGE ps;
  2578. #endif
  2579. { instruction *inst;
  2580.   int excpt = -1;
  2581.  
  2582.   inst = ps->inst;
  2583.  
  2584.   switch (OPCODE (inst))
  2585.     {
  2586.  
  2587.     case Y_ABS_S_OP:
  2588.     case Y_ABS_D_OP:
  2589.     case Y_ADD_S_OP:
  2590.     case Y_ADD_D_OP:
  2591.       Count (ps) = ((Count (ps) == 0) ? 0 : Count (ps) - 1);
  2592.       /* Should trap on inexact/overflow/underflow */
  2593.       break;
  2594.  
  2595.  
  2596.     case Y_C_F_S_OP:
  2597.     case Y_C_UN_S_OP:
  2598.     case Y_C_EQ_S_OP:
  2599.     case Y_C_UEQ_S_OP:
  2600.     case Y_C_OLE_S_OP:
  2601.     case Y_C_ULE_S_OP:
  2602.     case Y_C_SF_S_OP:
  2603.     case Y_C_NGLE_S_OP:
  2604.     case Y_C_SEQ_S_OP:
  2605.     case Y_C_NGL_S_OP:
  2606.     case Y_C_LT_S_OP:
  2607.     case Y_C_NGE_S_OP:
  2608.     case Y_C_LE_S_OP:
  2609.     case Y_C_NGT_S_OP:
  2610.       /* FpCond is set in Ex2 but not in Ex3 */
  2611.       if (Count (ps) == 0) {
  2612.     FpCond = VALUE (ps);
  2613.     Count (ps) = -1;
  2614.       }
  2615.       else
  2616.     Count (ps) = 0;
  2617.       break;
  2618.  
  2619.  
  2620.     case Y_C_F_D_OP:
  2621.     case Y_C_UN_D_OP:
  2622.     case Y_C_EQ_D_OP:
  2623.     case Y_C_UEQ_D_OP:
  2624.     case Y_C_OLE_D_OP:
  2625.     case Y_C_ULE_D_OP:
  2626.     case Y_C_SF_D_OP:
  2627.     case Y_C_NGLE_D_OP:
  2628.     case Y_C_SEQ_D_OP:
  2629.     case Y_C_NGL_D_OP:
  2630.     case Y_C_LT_D_OP:
  2631.     case Y_C_NGE_D_OP:
  2632.     case Y_C_LE_D_OP:
  2633.     case Y_C_NGT_D_OP:
  2634.       /* What to do? */
  2635.       if (Count (ps) == 0) {
  2636.     FpCond = VALUE (ps);
  2637.     Count (ps) = -1;
  2638.       }
  2639.       else
  2640.     Count (ps) = 0;
  2641.       break;
  2642.  
  2643.     case Y_CFC1_OP:
  2644.       /* What to do? */
  2645.       break;
  2646.  
  2647.     case Y_CTC1_OP:
  2648.       /* What to do? */
  2649.       break;
  2650.  
  2651.     case Y_CVT_D_S_OP:
  2652.     case Y_CVT_D_W_OP:
  2653.     case Y_CVT_S_D_OP:
  2654.     case Y_CVT_S_W_OP:
  2655.     case Y_CVT_W_D_OP:
  2656.     case Y_CVT_W_S_OP:
  2657.       Count (ps) = ((Count (ps) == 0) ? 0 : Count (ps) - 1);
  2658.       break;
  2659.  
  2660.     case Y_DIV_S_OP:
  2661.     case Y_DIV_D_OP:
  2662.       Count (ps) = ((Count (ps) == 0) ? 0 : Count (ps) - 1);
  2663.       break;
  2664.  
  2665.     case Y_LWC1_OP:
  2666.     case Y_MFC1_OP:
  2667.     case Y_MTC1_OP:
  2668.       Count (ps) = 0;
  2669.       break;
  2670.  
  2671.     case Y_MOV_S_OP:
  2672.     case Y_MOV_D_OP:
  2673.     case Y_NEG_S_OP:
  2674.     case Y_NEG_D_OP:
  2675.     case Y_SUB_S_OP:
  2676.     case Y_SUB_D_OP:
  2677.       Count (ps) = ((Count (ps) == 0) ? 0 : Count (ps) - 1);
  2678.       break;
  2679.  
  2680.     case Y_MUL_S_OP:
  2681.     case Y_MUL_D_OP:
  2682.       Count (ps) = ((Count (ps) == 0) ? 0 : Count (ps) - 1);
  2683.       break;
  2684.  
  2685.     default:
  2686.       /* What to do?  */
  2687.       break;
  2688.     }
  2689.  
  2690.   return (excpt);
  2691.  
  2692. }
  2693.  
  2694.  
  2695.  
  2696.  
  2697. /* Process FPA FWB */
  2698.  
  2699. #ifdef __STDC__
  2700. static int
  2701. process_f_fwb (PIPE_STAGE ps)
  2702. #else
  2703. static int
  2704. process_f_fwb (ps)
  2705.   PIPE_STAGE ps;
  2706. #endif
  2707. { instruction *inst;
  2708.  
  2709.   inst = ps->inst;
  2710.  
  2711.   switch (OPCODE (inst))
  2712.     {       /* FPA Operations */
  2713.  
  2714.     case Y_DIV_S_OP:
  2715.       set_present(FD (inst));
  2716.       SET_FPR_S (FD (inst), FPvalue (ps));
  2717.       break;
  2718.  
  2719.     case Y_DIV_D_OP:
  2720.       set_present(FD (inst));
  2721.       SET_FPR_D (FD (inst), FPvalue (ps));
  2722.       break;
  2723.  
  2724.     case Y_MUL_S_OP:
  2725.       set_present(FD (inst));
  2726.       SET_FPR_S (FD (inst), FPvalue (ps));
  2727.       break;
  2728.  
  2729.     case Y_MUL_D_OP:
  2730.       set_present(FD (inst));
  2731.       SET_FPR_D (FD (inst), FPvalue (ps));
  2732.       break;
  2733.  
  2734.     case Y_ABS_S_OP:
  2735.       set_present(FD (inst));
  2736.       SET_FPR_S (FD (inst), FPvalue (ps));
  2737.       break;
  2738.  
  2739.     case Y_ABS_D_OP:
  2740.       set_present(FD (inst));
  2741.       SET_FPR_D (FD (inst), FPvalue (ps));
  2742.       break;
  2743.  
  2744.     case Y_ADD_S_OP:
  2745.       set_present(FD (inst));
  2746.       SET_FPR_S (FD (inst), FPvalue (ps));
  2747.       /* Should trap on inexact/overflow/underflow */
  2748.       break;
  2749.  
  2750.     case Y_ADD_D_OP:
  2751.       { set_present(FD (inst));
  2752.     SET_FPR_D (FD (inst), FPvalue (ps));
  2753.  
  2754.     /* Should trap on inexact/overflow/underflow */
  2755.     break;
  2756.       }
  2757.  
  2758.     case Y_C_F_S_OP:
  2759.     case Y_C_UN_S_OP:
  2760.     case Y_C_EQ_S_OP:
  2761.     case Y_C_UEQ_S_OP:
  2762.     case Y_C_OLE_S_OP:
  2763.     case Y_C_ULE_S_OP:
  2764.     case Y_C_SF_S_OP:
  2765.     case Y_C_NGLE_S_OP:
  2766.     case Y_C_SEQ_S_OP:
  2767.     case Y_C_NGL_S_OP:
  2768.     case Y_C_LT_S_OP:
  2769.     case Y_C_NGE_S_OP:
  2770.     case Y_C_LE_S_OP:
  2771.     case Y_C_NGT_S_OP:
  2772.       /* Nothing to do.  FpCond is computed in EX1 and
  2773.      written in EX2.  */
  2774.       break;
  2775.  
  2776.     case Y_C_F_D_OP:
  2777.     case Y_C_UN_D_OP:
  2778.     case Y_C_EQ_D_OP:
  2779.     case Y_C_UEQ_D_OP:
  2780.     case Y_C_OLE_D_OP:
  2781.     case Y_C_ULE_D_OP:
  2782.     case Y_C_SF_D_OP:
  2783.     case Y_C_NGLE_D_OP:
  2784.     case Y_C_SEQ_D_OP:
  2785.     case Y_C_NGL_D_OP:
  2786.     case Y_C_LT_D_OP:
  2787.     case Y_C_NGE_D_OP:
  2788.     case Y_C_LE_D_OP:
  2789.     case Y_C_NGT_D_OP:
  2790.       /* Nothing to do.  FpCond is computed in EX1 and
  2791.      written in EX2.  */
  2792.       break;
  2793.  
  2794.     case Y_CFC1_OP:
  2795.       /* What to do? */
  2796.       break;
  2797.  
  2798.     case Y_CTC1_OP:
  2799.       /* What to do? */
  2800.       break;
  2801.  
  2802.     case Y_CVT_D_S_OP:
  2803.       set_present(FD (inst));
  2804.       SET_FPR_D (FD (inst), FPvalue (ps));
  2805.       break;
  2806.  
  2807.     case Y_CVT_D_W_OP:
  2808.       set_present(FD (inst));
  2809.       SET_FPR_D (FD (inst), FPvalue (ps));
  2810.       break;
  2811.  
  2812.     case Y_CVT_S_D_OP:
  2813.       set_present(FD (inst));
  2814.       SET_FPR_S (FD (inst), FPvalue (ps));
  2815.       break;
  2816.  
  2817.     case Y_CVT_S_W_OP:
  2818.       set_present(FD (inst));
  2819.       SET_FPR_S (FD (inst), FPvalue (ps));
  2820.       break;
  2821.  
  2822.     case Y_CVT_W_D_OP:
  2823.       { int val = FPvalue (ps);
  2824.     set_present(FD (inst));
  2825.     SET_FPR_W (FD (inst), val);
  2826.     break;
  2827.       }
  2828.  
  2829.     case Y_CVT_W_S_OP:
  2830.       set_present(FD (inst));
  2831.       SET_FPR_W (FD (inst), FPvalue (ps));
  2832.       break;
  2833.  
  2834.  
  2835.     case Y_LWC1_OP:
  2836.       {
  2837.     reg_word word;
  2838.     float *wp = (float *) &word;
  2839.  
  2840.  
  2841.     word = VALUE (ps);
  2842.     set_single_present(FT (inst));
  2843.     FGR [FT (inst)] = *wp; /* Fool coercion */
  2844.  
  2845.       }
  2846.  
  2847.  
  2848.     case Y_MFC1_OP:
  2849.       /* Nothing to do */
  2850.       break;
  2851.  
  2852.  
  2853.     case Y_MOV_S_OP:
  2854.       set_present(FD (inst));
  2855.       SET_FPR_S (FD (inst), FPvalue (ps));
  2856.       break;
  2857.  
  2858.     case Y_MOV_D_OP:
  2859.       set_present(FD (inst));
  2860.       SET_FPR_D (FD (inst), FPvalue (ps));
  2861.       break;
  2862.  
  2863.     case Y_MTC1_OP:
  2864.       { reg_word word = VALUE (ps);
  2865.     float *wp = (float *) &word;
  2866.  
  2867.     word = VALUE (ps);
  2868.     set_single_present(RD (inst));
  2869.     FGR [RD (inst)] = *wp; /* RD not FS, fool coercion */
  2870.     break;
  2871.       }
  2872.  
  2873.     case Y_NEG_S_OP:
  2874.       set_present(FD (inst));
  2875.       SET_FPR_S (FD (inst), FPvalue (ps));
  2876.       break;
  2877.  
  2878.     case Y_NEG_D_OP:
  2879.       set_present(FD (inst));
  2880.       SET_FPR_D (FD (inst), FPvalue (ps));
  2881.       break;
  2882.  
  2883.     case Y_SUB_S_OP:
  2884.       set_present(FD (inst));
  2885.       SET_FPR_S (FD (inst), FPvalue (ps));
  2886.       break;
  2887.  
  2888.     case Y_SUB_D_OP:
  2889.       set_present(FD (inst));
  2890.       SET_FPR_D (FD (inst), FPvalue (ps));
  2891.       break;
  2892.  
  2893.     default:
  2894.       fatal_error ("Unknown instruction type: %d\n", OPCODE (inst));
  2895.       break;
  2896.     }
  2897. }
  2898.  
  2899.  
  2900.  
  2901. /* Auxiliary functions. */
  2902. PIPE_STAGE head_pool;
  2903.  
  2904. #ifdef __STDC__
  2905. static void
  2906. init_stage_pool (void)
  2907. #else
  2908. static void
  2909. init_stage_pool ()
  2910. #endif
  2911. {
  2912.   PIPE_STAGE tmp;
  2913.   int i;
  2914.  
  2915.   head_pool = (PIPE_STAGE) malloc(12 * sizeof(struct pipe_stage));
  2916.   tmp = head_pool;
  2917.  
  2918.   /* chain up the pool of entries */
  2919.   for (i=0; i < 11; i++) {
  2920.     tmp->next = tmp + 1;
  2921.     tmp = tmp->next;
  2922.   }
  2923.  
  2924.   /* fix up the end */
  2925.   tmp->next = NULL;
  2926. }
  2927.  
  2928.  
  2929. #ifdef __STDC__
  2930. static PIPE_STAGE
  2931. stage_alloc (void)
  2932. #else
  2933. static PIPE_STAGE
  2934. stage_alloc ()
  2935. #endif
  2936. {
  2937.   PIPE_STAGE tmp;
  2938.  
  2939.   if (head_pool == NULL)
  2940.     init_stage_pool();
  2941.  
  2942.   tmp = head_pool;
  2943.   head_pool = head_pool->next;
  2944.   tmp->exception = 0;
  2945.   tmp->next = NULL;
  2946.   return tmp;
  2947. }
  2948.  
  2949.  
  2950. #ifdef __STDC__
  2951. static int
  2952. stage_dealloc (PIPE_STAGE ps)
  2953. #else
  2954. static int
  2955. stage_dealloc (ps)
  2956.   PIPE_STAGE ps;
  2957. #endif
  2958. {
  2959.   if (ps == NULL)
  2960.     return(0);
  2961.  
  2962.   if (head_pool == NULL) {
  2963.     head_pool = ps;
  2964.     ps->next = NULL;
  2965.   }
  2966.   else {
  2967.     ps->next = head_pool;
  2968.     head_pool = ps;
  2969.   }
  2970. }
  2971.  
  2972.  
  2973.  
  2974. #ifdef __STDC__
  2975. static int
  2976. pipe_dealloc (int stage, PIPE_STAGE alu[], PIPE_STAGE fpa[])
  2977. #else
  2978. static int
  2979. pipe_dealloc (stage, alu, fpa)
  2980.   int stage;
  2981.   PIPE_STAGE alu[], fpa[];
  2982. #endif
  2983. {
  2984.   int i;
  2985.  
  2986.   for(i=0; i < stage; i++) {
  2987.     stage_dealloc(alu[i]);
  2988.     alu[i] = NULL;
  2989.     stage_dealloc(fpa[i]);
  2990.     fpa[i] = NULL;
  2991.   }
  2992. }
  2993.  
  2994.  
  2995.  
  2996.  
  2997. #ifdef __STDC__
  2998. static void
  2999. long_multiply (reg_word v1, reg_word v2, reg_word *hi, reg_word *lo)
  3000. #else
  3001. static void
  3002. long_multiply (v1, v2, hi, lo)
  3003.      reg_word v1, v2;
  3004.      reg_word *hi, *lo;
  3005. #endif
  3006. {
  3007.   register long a, b, c, d;
  3008.   register long bd, ad, cb, ac;
  3009.   register long mid, mid2, carry_mid = 0;
  3010.  
  3011.   a = (v1 >> 16) & 0xffff;
  3012.   b = v1 & 0xffff;
  3013.   c = (v2 >> 16) & 0xffff;
  3014.   d = v2 & 0xffff;
  3015.  
  3016.   bd = b * d;
  3017.   ad = a * d;
  3018.   cb = c * b;
  3019.   ac = a * c;
  3020.  
  3021.   mid = ad + cb;
  3022.   if (ARITH_OVFL (mid, ad, cb))
  3023.     carry_mid = 1;
  3024.  
  3025.   mid2 = mid + ((bd >> 16) & 0xffff);
  3026.   if (ARITH_OVFL (mid2, mid, ((bd >> 16) & 0xffff)))
  3027.     carry_mid += 1;
  3028.  
  3029.   *lo = (bd & 0xffff) | ((mid2 & 0xffff) << 16);
  3030.   *hi = ac + (carry_mid << 16) + ((mid2 >> 16) & 0xffff);
  3031. }
  3032.  
  3033.  
  3034.  
  3035. #ifdef __STDC__
  3036. void
  3037. print_pipeline (void)
  3038. #else
  3039. void
  3040. print_pipeline ()
  3041. #endif
  3042. {
  3043.   char *buf;
  3044.   int limit;
  3045.  
  3046.   buf = (char *) malloc (8*K);
  3047.   *buf = '\0';
  3048.   limit = 8*K;
  3049.  
  3050.   print_pipeline_internal (buf);
  3051.   write_output (pipe_out, buf);
  3052.   free (buf);
  3053. }
  3054.  
  3055.  
  3056. #ifdef __STDC__
  3057. void
  3058. print_pipeline_internal (char *buf)
  3059. #else
  3060. void
  3061. print_pipeline_internal (buf)
  3062.   char *buf;
  3063. #endif
  3064. {
  3065.   int i;
  3066.   PIPE_STAGE tmp;
  3067.  
  3068.   sprintf(buf,"*** Control processor pipeline\n");
  3069.   buf += strlen(buf);
  3070.  
  3071.   sprintf (buf, "WB\t"); buf += strlen(buf);
  3072.   if (alu[WB]) {
  3073.     buf += print_inst_internal (buf, 8*K, alu[WB]->inst, alu[WB]->pc) - 1;
  3074.     if (EXCPT(alu[WB])) {
  3075.       sprintf (buf, "\t[%s EXCPT]", EXCPT_STR((EXCPT(alu[WB])>>2) & 0xf));
  3076.       buf += strlen(buf);
  3077.     }
  3078.   }
  3079.   else {
  3080.     sprintf (buf, "<none>");
  3081.     buf += strlen(buf);
  3082.   }
  3083.   sprintf (buf++, "\n");
  3084.  
  3085.   sprintf (buf, "MEM\t"); buf += strlen(buf);
  3086.   if (alu[MEM]) {
  3087.     buf += print_inst_internal (buf, 8*K, alu[MEM]->inst, alu[MEM]->pc) - 1;
  3088.     if (EXCPT(alu[MEM])) {
  3089.       sprintf (buf, "\t[%s EXCPT]", EXCPT_STR((EXCPT(alu[MEM])>>2) & 0xf));
  3090.       buf += strlen(buf);
  3091.     }
  3092.     if (STAGE(alu[MEM]) == MEM_STALL) {
  3093.       sprintf(buf,"\t(STALLED)");
  3094.       buf += strlen(buf);
  3095.     }
  3096.   }
  3097.   else {
  3098.     sprintf (buf, "<none>");
  3099.     buf += strlen(buf);
  3100.   }
  3101.   sprintf (buf++, "\n");
  3102.  
  3103.   sprintf (buf, "EX\t"); buf += strlen(buf);
  3104.   if (alu[EX]) {
  3105.     buf += print_inst_internal (buf, 8*K, alu[EX]->inst, alu[EX]->pc) - 1;
  3106.     if (EXCPT(alu[EX])) {
  3107.       sprintf (buf, "\t[%s EXCPT]", EXCPT_STR(EXCPT(alu[EX])>>2 & 0xf));
  3108.       buf += strlen(buf);
  3109.     }
  3110.   }
  3111.   else {
  3112.     sprintf (buf,"<none>");
  3113.     buf += strlen(buf);
  3114.   }
  3115.   sprintf (buf++, "\n");
  3116.  
  3117.   sprintf (buf, "ID\t"); buf += strlen(buf);
  3118.   if (alu[ID]) {
  3119.     buf += print_inst_internal (buf, 8*K, alu[ID]->inst, alu[ID]->pc) - 1;
  3120.     if (EXCPT(alu[ID])) {
  3121.       sprintf (buf, "\t[%s EXCPT]", EXCPT_STR((EXCPT(alu[ID])>>2) & 0xf));
  3122.       buf += strlen(buf);
  3123.     }
  3124.   }
  3125.   else {
  3126.     sprintf (buf,"<none>");
  3127.     buf += strlen(buf);
  3128.   }
  3129.   sprintf (buf++, "\n");
  3130.  
  3131.   sprintf (buf, "IF\t"); buf += strlen(buf);
  3132.   if (alu[IF]) {
  3133.     buf += print_inst_internal (buf, 8*K, alu[IF]->inst, alu[IF]->pc) - 1;
  3134.     if (STAGE(alu[IF]) == IF_STALL) {
  3135.       sprintf(buf,"\t(STALLED)");
  3136.       buf += strlen(buf);
  3137.     }
  3138.   }
  3139.   else {
  3140.     sprintf (buf, "<none>");
  3141.     buf += strlen(buf);
  3142.   }
  3143.   sprintf (buf++, "\n");
  3144.  
  3145.   sprintf (buf, "*** Multiply/Divide Unit\n"); buf += strlen(buf);
  3146.   sprintf (buf, "HI 0x%08x\tLO 0x%08x\n", MDU.hi_val, MDU.lo_val);
  3147.   buf += strlen(buf);
  3148.  
  3149.   sprintf (buf, "*** Floating point pipeline\n"); buf += strlen(buf);
  3150.  
  3151.   sprintf (buf, "FWB\t"); buf += strlen(buf);
  3152.  
  3153.   tmp = fpa[FPA_FWB];
  3154.   for (i = 0; i < 2; i++)
  3155.     {
  3156.       if (i>0) {
  3157.     sprintf (buf, "\t");
  3158.     buf++;
  3159.       }
  3160.       if (!tmp)    {
  3161.     sprintf (buf,"<none>");
  3162.     buf += strlen(buf);
  3163.       }
  3164.       else {
  3165.     buf += print_inst_internal (buf, 8*K, tmp->inst, tmp->pc) - 1;
  3166.     tmp = tmp->next;
  3167.       }
  3168.       sprintf (buf++, "\n");
  3169.     }
  3170.  
  3171.   sprintf (buf, "FEX3\t"); buf += strlen(buf);
  3172.   tmp = fpa[FPA_EX3];
  3173.   for (i = 0; i < 4; i++)
  3174.     {
  3175.       if (i>0) {
  3176.     sprintf (buf, "\t");
  3177.     buf++;
  3178.       }
  3179.       if (!tmp)    {
  3180.     sprintf (buf,"<none>");
  3181.     buf += strlen(buf);
  3182.       }
  3183.       else {
  3184.     buf += print_inst_internal (buf, 8*K, tmp->inst, tmp->pc) - 1;
  3185.     tmp = tmp->next;
  3186.       }
  3187.       sprintf (buf++, "\n");
  3188.     }
  3189.  
  3190.   sprintf (buf, "FEX2\t"); buf += strlen(buf);
  3191.   if (fpa[FPA_EX2])
  3192.     buf += print_inst_internal(buf, 8*K,fpa[FPA_EX2]->inst,fpa[FPA_EX2]->pc) - 1;
  3193.   else {
  3194.     sprintf (buf,"<none>");
  3195.     buf += strlen(buf);
  3196.   }
  3197.   sprintf (buf++, "\n");
  3198.  
  3199.    sprintf (buf, "FEX1\t"); buf += strlen(buf);
  3200.   if (fpa[FPA_EX1])
  3201.     buf += print_inst_internal(buf, 8*K,fpa[FPA_EX1]->inst,fpa[FPA_EX1]->pc) - 1;
  3202.   else {
  3203.     sprintf (buf,"<none>");
  3204.     buf += strlen(buf);
  3205.   }
  3206.   sprintf (buf++, "\n");
  3207.  
  3208.   sprintf (buf, "*** Bypass Registers, Values\n");
  3209.   buf += strlen(buf);
  3210.  
  3211.   sprintf (buf, "MEM %$%d 0x%08x   EX %$%d 0x%08x\n",MEM_bp_reg, MEM_bp_val, EX_bp_reg, EX_bp_val);
  3212.   buf += strlen(buf);
  3213.  
  3214.   sprintf (buf, "*** Write Back Buffer\n");
  3215.   buf += strlen(buf);
  3216.  
  3217.   sprintf (buf, "%s\n", print_write_buffer());
  3218.   buf += strlen(buf);
  3219. }
  3220.  
  3221.  
  3222.